【Webpack】之 配合后端渲染
原创
©著作权归作者所有:来自51CTO博客作者DonaldY的原创作品,请联系作者获取转载授权,否则将追究法律责任
为什么学习Webpack?
- 对之前开发形式的厌烦,想打破
- 更好模块管理
- 安全,对文件压缩,使外者不易看出
- 减少重复工作
代码分割
- 分离业务代码 和 第三方依赖
- 分离业务代码 和 业务公共代码 和第三方依赖
- 分离首次加载 和 访问后加载的代码
├─build # 编译后生成的所有代码、资源(图片、字体等,虽然只是简单的从源目录迁移过来)
├─node_modules # 利用npm管理的所有包及其依赖
├─index.html # 仅作为重定向使用
├─package.json # npm的配置文件
├─webpack-config # 存放分拆后的webpack配置文件
│ ├─base # 主要是存放一些变量
├─webpack.config.js # 生产环境的webpack配置文件(无实质内容,仅为组织整理)
├─webpack.dev.config.js # 开发环境的webpack配置文件(无实质内容,仅为组织整理)
├─src # 当前项目的源码
├─pages # 各个页面独有的部分,如入口文件、只有该页面使用到的css、模板文件等
│ ├─alert # 业务模块
│ │ └─index # 具体页面
│ ├─index # 业务模块
│ │ ├─index # 具体页面
│ │ └─login # 具体页面
│ │ └─templates # 如果一个页面的HTML比较复杂,可以分成多块再拼在一起
│ └─user # 业务模块
│ ├─edit-password # 具体页面
│ └─modify-info # 具体页面
└─public-resource # 各个页面使用到的公共资源
├─components # 组件,可以是纯HTML,也可以包含js/css/image等,看自己需要
│ ├─footer # 页尾
│ ├─header # 页头
│ ├─side-menu # 侧边栏
│ └─top-nav # 顶部菜单
├─iconfont # iconfont的字体文件
├─imgs # 公用的图片资源
└─layout # UI布局,组织各个组件拼起来,因应需要可以有不同的布局套路
├─layout # 具体的布局套路
└─layout-without-nav # 具体的布局套路
需要生产环境和开发环境
- 因为后端服务器启动,资源请求路径就会改变。
- 开发环境热模板更新
生产环境
- 提取公共代码
- 压缩混淆
- 文件压缩 或是 Base64编码
- 去除无用的代码
(1)html-load,html片段插入html
<%= require('html-loader!../../public-resource/components/header/header.html') %>
npm配置 : npm install html-loader --save-dev
不需要全局配置html-loader(即不需要在module中配置)
详见:http://www.imooc.com/article/18513
(2)提取css
- npm配置 :
npm install extract-text-webpack-plugin --save-dev
- 在plugin中配置
// 声明
var ExtractTextPlugin = require('extract-text-webpack-plugin');
// 在plugin中配置
/* 抽取出chunk的css */
new ExtractTextPlugin('css/[name].css')
(3)如何在html中引入css文件
在对应的js文件中,require
(4)提取所有公用的部分(js)
如果引入的js文件中有公共部分,则会被提取出来
new webpack.optimize.CommonsChunkPlugin({
name:'commons/common',
filename: '[name].js',
minChunks: 4 // 出现4次,则提出
}),
(5)提取html
- npm配置 :
npm install html-webpack-plugin --save-dev
- 在plugin中配置
// 声明
var HtmlWebpackPlugin = require('html-webpack-plugin');
// 因为每提取一个html,就要new HtmlWebpackPlugin
// 所以一个公共方法,进行提取
// 用于判断是否为html文件
function isHtmlFile(str) {
var objRegExp = /\.html/;
return objRegExp.test(str);
}
pageArr.forEach((page) => {
if (isHtmlFile(page)) {
page = page.substring(0, page.lastIndexOf('.'));
const htmlPlugin = new HtmlWebpackPlugin({
filename: `/pages/${page}.html`,
template: path.resolve(dirVars.pagesDir, `./${page}.html`),
chunks: ['commons/common', page], // 公共文件需先导入, 同时公共js也在这配置
xhtml: true;
(6)图片导入
- npm配置:
npm install file-loader url-loader img-loader --save-dev
- 在module中配置
{
test:'url-loader',
options: {
name: '[name].[ext]',
limit: 8192,
publicPath: '',
outputPath: 'build/',
useRelativePath: true
}
},
{ // 用于压缩
loader:'img-loader',
options: {
pngquant: {
quality: 80}
}
}
]
}
(7)iconfont
- npm配置 同 图片导入
- 在module中配置
// iconfont
test:/\.(eot|woff2|woff|ttf|svg)$/,
use: [
{
loader: 'url-loader',
options: {
name: '[name].[ext]',
limit: 8192,
publicPath: '',
outputPath: 'build/',
useRelativePath: true
(8)分生产环境和开发环境
devServer 与 ExtractTextPlugin 可能相冲突
开发模式用 style-loader
(9)Babel
npm install babel-loader babel-core babel-preset-env -save-dev
babel-core:babel的核心包;
babel-loader:babel的loader包;
babel-preset-env:解析es6的包;
// modules 中添加
{
test: /\.js$/,
include: dirVars.srcRootDir,
loader: 'babel-loader',
options: {
presets: [['env', { loose: true }]],
cacheDirectory: true,
plugins: ['transform-runtime', 'lodash']
}
}
函数和方法 没有被 babel处理
比如:
- Generator
- Set
- Map
- Array.from
- Array.prototype.includes
npm install babel-polyfill babel-runtime --save-dev
全局垫片
为开发应用准备
使用在 引入:import "babel-polyfill"
npm install babel-plugin-transform-runtime -save-dev
npm install babel-runtime -save-dev
局部垫片
为开发框架准备
使用 添加文件 .babelrc
(10)Tree Shaking
使用场景(减少打包的代码,只打包使用到的代码,针对CSS和js)
- 常规优化
- 引入第三方库的某一个功能
针对js进行过滤
针对CSS进行过滤 (Purify CSS)
purify css
npm install purifycss-webpack purify-css --save-dev
glob-all 处理多路径
npm install glob-all --save-dev
var PurifyCss = require('purifycss-webpack');
var glob = require('glob-all');
针对lodash
npm install babel-plugin-lodash --save-dev
(11)Source Map 调试
Why?
- 使开发代码与浏览器编译后的代码一致
- 方便在浏览器中调试,进行代码映射
添加 js source map
只需添加devtool: 'cheap-module-source-map'
当然cheap-module-source-map
根据需求进行更改
添加 css source map
只需在每个跟css有个的loader中的options下添加sourceMap: true
// 比如
{
loader: 'css-loader',
options: {
sourceMap: true
(12)EsLint检查代码式格
js 规范(Javascript Standard Style) https://standardjs.com/
安装
npm install eslint eslint-loader eslint-plugin-html eslint-friendly-formatter --save-dev
npm install eslint-config-standard eslint-plugin-promise eslint-plugin-node eslint-plugin-import eslint-plugin-standard --save-dev
npm install babel-eslint --save-dev