为什么学习Webpack?

  1. 对之前开发形式的厌烦,想打破
  2. 更好模块管理
  3. 安全,对文件压缩,使外者不易看出
  4. 减少重复工作

代码分割

  1. 分离业务代码 和 第三方依赖
  2. 分离业务代码 和 业务公共代码 和第三方依赖
  3. 分离首次加载 和 访问后加载的代码
├─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 # 具体的布局套路
需要生产环境和开发环境
  1. 因为后端服务器启动,资源请求路径就会改变。
  2. 开发环境热模板更新
生产环境
  1. 提取公共代码
  2. 压缩混淆
  3. 文件压缩 或是 Base64编码
  4. 去除无用的代码

(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

  1. npm配置 :​​npm install extract-text-webpack-plugin --save-dev​
  2. 在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

  1. npm配置 :​​npm install html-webpack-plugin --save-dev​
  2. 在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)图片导入

  1. npm配置:​​npm install file-loader url-loader img-loader --save-dev​
  2. 在module中配置
{
test:'url-loader',
options: {
name: '[name].[ext]',
limit: 8192,
publicPath: '',
outputPath: 'build/',
useRelativePath: true
}
},
{ // 用于压缩
loader:'img-loader',
options: {
pngquant: {
quality: 80}
}
}

]
}


(7)iconfont

  1. npm配置 同 图片导入
  2. 在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处理
比如:
  1. Generator
  2. Set
  3. Map
  4. Array.from
  5. 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)

  1. 常规优化
  2. 引入第三方库的某一个功能
针对js进行过滤
// plugin 中添加
new
针对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?
  1. 使开发代码与浏览器编译后的代码一致
  2. 方便在浏览器中调试,进行代码映射


    添加 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​