基础知识

模块化

模块化

js模块化
  1. js模块化
    命名空间
    1. 命名空间
      1. 一个对象 语法:
      库名.类别名.方法名
      
      1
      var NameSpace = {}
      NameSpace.type = NameSpace.type || {}
      NameSpace.type.method = function(){}
      
      1
      2
      3
    common.js
    1. common.js (只能在服务器端使用)
      1. 一个文件为一个模块
      2. 只能通过module.exports暴露接口
      3. 通过require引入模块
      4. 同步执行
    Amd/Cmd/Um
    1. Amd/Cmd/Umd (规范化模块化开发)
      • Amd
        1. 异步的模块定义
        2. 使用define定义模块
        3. 使用require加载模块
        4. 特点是依赖前置,提前执行
      • Cmd
        1. 一个文件为一个模块
        2. 使用define定义模块
        3. 使用require加载模块
        4. 特点是尽可能懒执行
      • Umd (通用解决方案)
        1. 首选判断是否支持Amd再判断是否支持common.js,如果都不支持,则将其定义为全局变量
    Es6 module
    1. Es6 module (es6模块化规范)
      1. 一个文件为一个模块
      2. 使用import引入模块
      3. 使用export暴露接口
css模块化
  1. css模块化
    1. OOCSS (设计结构分离)
    2. SMACSS (减少代码量,代码维护)
    3. Atomic CSS(原则化css)
    4. MCSS (多层级css)
    5. AMCSS (针对属性进行css设计)
    6. BEM (BlockElementModifier其实是块(block)、元素(element)、修饰符(modifier)

核心概念

Entry
  1. Entry(打包入口)
    1. 告诉webpack,这里的所有依赖模块,
    2. 也是打包的入口
    3. 可以是单个或多个
      1. 可以是一个文件

        module.exports = {
           entry : 'index.js'
        }
        
        1
        2
        3
      2. 可以是一个数组

        module.exports = {
           entry : ['index.js','vendor.js']
        }
        
        1
        2
        3
      3. 可以是一个key value形式的对象

        module.exports = {
           entry : {
               index : 'index.js'
           }
        }
        
        1
        2
        3
        4
        5
        1. 当entry是一个对象的时候,好处是
          1. 知道每一个entry对应的是什么
          2. 如果想要继续添加一个新的入口,可以继续指定key,可扩展性强
            module.exports = {
               entry : {
                   index: 'index.js',
                   home:  'home.js',
                   vendor: ['vendor.js','app.js']
               }
            }
            
            1
            2
            3
            4
            5
            6
            7
Output
  1. Output(打包输出)
    1. 可以是一个或多个

      1. 一个
        module.exports = {
           entry : 'index.js',
           output: {
               filename: 'index.min.js'
           }
        }
        
        1
        2
        3
        4
        5
        6
      2. 多个
        module.exports = {
           entry : {
               index: 'index.js',
               home:  'home.js',
           }
           output: {
               filename: '[name].min.[hash:5].js'
           }
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        name 表示的是entry的name,hash是在webpack打包的唯一的hash码
    2. 自定义规则

Loaders
  1. Loaders (处理其他类型的资源文件)
    1. 处理文件
    2. 转换为模块
      1. code
      module.exports = {
         module:{
             rules: [
                 {
                     test: /\.css$/,
                     use: 'css-loader'
                 }
             ]
         }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      满足以.css结尾的使用,用css-loader转换
      • 常用loader
        1. 编译相关
          • babel-loader,ts-loader
        2. 样式相关
          • style-loader, css-loader, less-loader, postcss-loader
        3. 文件相关
          • file-loaderurl-loader
Plugins
  1. Plugins (压缩代码,混淆代码)
    1. 可以参与到整个打包的过程
    2. 打包优化和压缩
    3. 配置编译时的变量
      • code
      const webpack = require('webpack')
      module.export = {
          plugins:[
             new webpack.optimize.UglifyJsPlugin()
          ]
      }
      
      1
      2
      3
      4
      5
      6
      • 常用Plugins
        1. 优化相关
          • CommonsChunkPlugin, UglifyjsWebpackPlugin
        2. 功能相关
          • ExtractTextWebpackPluginHtmlWebpackPlugin, hotmodulereplacementCopyWebpackPlugin
      • 相关名词
        1. Chunk (代码块)
        2. Bubdle (打包过的)
        3. Module (模块)

开发环境

webpack 命令

  1. webpack -h (可以看到命令行中所有的配置选项)
  2. webpack -v (查看版本号)
  3. webpack <entry> [<entry>] <output> (打包)

webpack 配置

  1. 安装webpack-cli cnpm i webpack-cli -g
    1. 可以交互式初始化一个项目 webpack-cli
    2. 可以进行项目迁移
  2. 打包js
    1. 如果想想直接使用webpack,则名称为webpack.config.js,否则执行命令为 webpack --config webpack.xxx.js
         //js文件没有发生变化,打包后的哈希值不会变化
         module.exports = {
             entry: {
                 app: './app.js'
             },
             output: {
                 filename: '[name].[hash:5].js'
             }
         }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9

框架配合

Vue-cli

  1. Vue-cli

Angular-cli

  1. Angular-cli

React-starter

  1. React-starter

文件处理

编译Es 6/7

Babel
  1. Babel
    Babel-loader
    1. Babel-loader
      1. webpack中使用Babel 1.
        cnpm install babel-loader@8.0.0-beta.0 @babel/core
        
        1
        1. npm init 一直回车生成package.json文件
        2. 新建文件app.js,index.html,webpack.config.js
          1. app.js
          2. index.html
          3. webpack.config.js
           module.exports = {
               entry: {
                   app: './app.js'
               },
               output: {
                   filename: '[name].[hash:5].js'
               },
               module:{
                   rules:[
                       {
                           test: /\.js$/,
                           use:{
                               loader: 'baber-loader',
                               options:{
                                   presets:['@babel/preset-env']
                               }
                           },
                           exclude:'/node_module/'
                       }
                   ]
               }
           }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          执行 cnpm install bebel-loader --save-dev, cnpm install babel-core --save-dev, cnpm install @babel/preset-env --save-dev
        3. Babel Parests中的targets参数(根据指定的参数,选择是否编译):
          1. targets.browsers(指定浏览器)数据来源于browsweslist
            1. target.browsers:"last 2 versions" (最后两个版本执行)
            2. target.browsers:">1%"(大于全球占有率1%的执行)
            3. 配置
            module.exports = {
                entry: {
                    app: './app.js'
                },
                output: {
                    filename: '[name].[hash:5].js'
                },
                module:{
                    rules:[
                        {
                            test: /\.js$/,
                            use:{
                                loader: 'baber-loader',
                                options:{
                                    presets:[
                                        ['@babel/preset-env',{
                                            targets : {
                                                browsers : ['> 1%','last 2 versions']
                                            }
                                        }]
                                    ]
                                }
                            },
                            exclude:'/node_module/'
                        }
                    ]
                }
            }
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
    Babel-Polyfill
    1. Babel-Polyfill(浏览器标注)
      1. 可以全局使用
      2. 为开发应用准备的
      3. 使用 1.
        yarn add babel-polyfill --save
        
        1
        import 'babel-polyfill' 
        
        1
    Babel Runtime Transform
    1. Babel Runtime Transform
      1. 局部使用
      2. 为开发框架准备的
      3. 使用 1.
        yarn add babel-plugin-transform-runtime --save-dev
        
        1
        yarn add babel-runtime --save
        
        1
        1. 项目文件夹下新建·babelrc文件,在该文件里进行配置
    .babelrc
    1. .babelrc文件的配置
      {
      presets:[
          ['@babel/preset-env',{
              targets : {
                  browsers : ['> 1%','last 2 versions']
              }
          }]
      ],
      plugins: ["@babel/plugin-transform-runtime"]
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
Typescript
  1. Typescript
    使用Typescript
    1. 使用Typescript
      1. 安装Typescript
        yarn add ts-loader --save-dev
        
        1
      2. webpack.config.js配置
          module.exports = {
              entry: {
                  app: './app.ts'
              },
              output: {
                  filename: '[name].[hash:5].js'
              },
              module:{
                  rules:[
                      {
                          test: /\.tsx?$/,
                          use:{
                              loader: 'ts-loader',
                              options:{
                                  presets:[
                                      ['@babel/preset-env',{
                                          targets : {
                                              browsers : ['> 1%','last 2 versions']
                                          }
                                      }]
                                  ]
                              }
                          },
                          exclude:'/node_module/'
                      }
                  ]
              }
          }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
      3. tsconfig.json
        {
          "compilerOptions": {
            "module": "commonjs",
            "target": "es5",
            "allowJs": true,
            "sourceMap": true
          },
          "exclude": [
            "node_modules"
          ]
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
      4. 使用lodash
        1. 安装yarn lodash --save
        2. 使用
          import * as _ from 'lodash'
          const arr = [1,5,6];
          console.log(_.chunk(arr));
          
          1
          2
          3
      5. 全局使用typings
        1. 安装
          yarn add typings -g
          
          1
        2. 使用
          typings install loadsh
          
          1
        3. 安装成功后,文件夹下会新生成 typings.json 的配置文件和typings 文件夹
        4. 需在tsconfig.json中添加配置,typeRoots是告诉ts打包编译的时候,要到什么地方去找申明文件,这时代码编译报错便有提示
          "typeRoots": [
            "./node_modules/@type",
            "./typings/modules"
          ]
          
          1
          2
          3
          4

打包优化

提取公共代码

  1. 提取公共代码
    好处
    1. 好处
      1. 减少代码冗余
      2. 提高加载速度
    使用插件CommonsChunkPlugin
    1. 使用插件CommonsChunkPlugin
      配置
      1. 只需要在配置中添加
           {
               plugins: [
                   new webpack.optimize.CommonsChunkPlugin(options)
               ]
           }
        
        1
        2
        3
        4
        5
      options的配置项
      1. options的配置项
        1. name/names 给那些文件提出来公用
        2. filename 打包后的文件名
        3. minChunks 接受的值是数字表示你这个公共代码出现的次数,也可以是函数,以及自定义逻辑
        4. chunks 指定代码提取范围
        5. children 在模块/所有模块查找公共模块
        6. deepChildren 在模块/所有模块查找公共模块
        7. async 异步公共代码块
      应用场景
      1. 应用场景
        1. 单页应用
        2. 单页应用+第三方依赖
        3. 多页引用 + 第三方依赖 + webpack生成代码
      配置
      1. 配置
        const webapck = require('webpack');
        const path = require('path');
        
        module.exports = {
            entry: {
                'pageA': './pageA',
                'pageB': './pageB',
                'vendor': ['lodash']
            },
            output: {
                path: path.resolve(__dirname, './dist'),
                filename: "[name].bundle.js",
                chunkFilename: "[name].chunk.js"
            },
        
            plugins: [
                new webapck.optimize.CommonsChunkPlugin({
                    name: 'common',
                    minChunks: 2
                })
            ]
        };
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        1. __dirname 当前文件路径
        2. 这样打包的缺点:没有区分第三方模块代码和业务代码
        3. 将配置优化为
            const webapck = require('webpack');
            const path = require('path');
            
            module.exports = {
                entry: {
                    'pageA': '.pageA',
                    'pageB': '.pageB',
                    'vendor': ['lodash'] //可以是一个数组。第三方包
                },
                output: {
                    path: path.resolve(__dirname, './dist'),
                    filename: "[name].bundle.js",
                    chunkFilename: "[name].chunk.js"
                },
            
                plugins: [
                    new webapck.optimize.CommonsChunkPlugin({
                        name: 'vendor',
                        minChunks: Infinity
                    }),
            
                    new webapck.optimize.CommonsChunkPlugin({
                        name: 'mainfest',
                        minChunks: Infinity
                    })
                ]
            };
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          1. 以上代码还可以再优化
            const webapck = require('webpack');
            const path = require('path');
            
            module.exports = {
                entry: {
                    'pageA': '.pageA',
                    'pageB': '.pageB',
                    'vendor': ['lodash']
                },
                output: {
                    path: path.resolve(__dirname, './dist'),
                    filename: "[name].bundle.js",
                    chunkFilename: "[name].chunk.js"
                },
            
                plugins: [
                    new webapck.optimize.CommonsChunkPlugin({
                        name: 'common',
                        minChunks: 2,
                        chunks: ['pageA', 'pageB']  //指定需要提取公共文件的范围提取
                    }),
            
                    new webapck.optimize.CommonsChunkPlugin({
                        names: ['vendor', 'mainfest'],
                        minChunks: Infinity
                    }),
                ]
            };
            
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29

代码分割和懒加载

  1. 代码分割和懒加载
    1. 在通过改变写代码的方式上实现代码分割和懒加载
      webapck methods
      1. webapck methods wenpack内置方法
        1. require.ensure 该方法接受四个参数,该方法动态的加载一个模块
          1. []: dependencies 依赖。加载进来,并不会执行,在callback中require下才会执行
          2. callback
          3. errorCallback 可省略
          4. chunkName
        2. require.include 后面直接一个参数。
          1. 引入进来不执行。
          2. 作用是:两个模块依赖了第三方模块。可以把第三方模块放在父模块里,在打包时,不在子模块加载,只加载与父模块
      ES2015 Loader spec
      1. ES2015 Loader spec
        1. 场景
          1. 分离业务代码 第三方代码
          2. 分离业务代码 业务公共代码 第三方依赖
          3. 分离首次加载 访问后加载的代码
        2. 实例
          1. webpack.config.js
            const webapck = require('webpack');
            const path = require('path');
            
            module.exports = {
                entry: {
                    'pageA': './pageA'
                },
                output: {
                    path: path.resolve(__dirname, './dist'),
                    filename: "[name].bundle.js",
                    chunkFilename: "[name].chunk.js"
                }
            };
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
          2. paegA.js
            import './subPageA'
            import './subPageB'
            
            require.ensure(['lodash'], function () {
                const _ = require('lodash');
                _.join([1, 2], 3);
            }, 'vendor');
            
            export default 'pageA'
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
          3. pageA中提取公共的模块subPageA和subPageB 1.pageA.js
            if(page === 'subPageA') {
                require.ensure(['./subPageA'], function() {
                    const subPageA = require('./subPageA');
                }, 'subPageA');
            } else if(page === 'subPageB') {
                require.ensure(['./subPageB'], function() {
                    const subPageB = require('./subPageB');
                }, 'subPageB');
            }
            
            require.ensure(['lodash'], function () {
                const _ = require('lodash');
                _.join([1, 2], 3);
            }, 'vendor');
            
            export default 'pageA'
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
          4. 动态import分割代码
            require.include('./moduleA');
            
            const page = 'subPageA';
            
            if(page === 'subPageA') {
                import(
                    /* webpackChunkName:'subPageA' */
                    './subPageA').then(function(subPageA) {
                    console.log(subPageA);
                })
            } else if(page === 'subPageB') {
                import(
                    /* webpackChunkName:'subPageA' */
                    './subPageB').then(function(subPageB) {
                    console.log(subPageB);
                })
            }
            
            require.ensure(['lodash'], function () {
                const _ = require('lodash');
                _.join([1, 2], 3);
            }, 'vendor');
            
            export default 'pageA'
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
          5. async分隔代码
            const webapck = require('webpack');
            const path = require('path');
            
            module.exports = {
                entry: {
                    'pageA': './pageA',
                    'pageB': './pageB',
                    'vendor': ['lodash']
                },
                output: {
                    path: path.resolve(__dirname, './dist'),
                    filename: "[name].bundle.js",
                    publicPath: "./dist/",
                    chunkFilename: "[name].chunk.js"
                },
            
                plugins: [
                    new webapck.optimize.CommonsChunkPlugin({
                        async: 'async-common',
                        children: true,
                        minChunks: 2
                    }),
                    new webapck.optimize.CommonsChunkPlugin({
                        names: ['vendor', 'mainfest'],
                        minChunks: Infinity
                    })
                ]
            };
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28

处理css

  1. 处理css
    1. style-loader
      1. style-loader 创建标签
        1. 安装
        yarn add css-loader style-loader --dev
        
        1
        1. app.js
        import "./style.css"
        
        1
        1. 配置
           const path = require('path');
           
           module.exports = {
               entry: {
                   app: './app.js'
               },
           
               output: {
                   path: path.resolve(__dirname, 'dist'),
                   filename: '[name].bundle.js',
                   publicPath: './dist/'
               },
           
               module: {
                   rules: [
                       {
                           test: /\.css$/,
                           use: [
                               {
                                   loader: 'style-loader'
                               },
                               {
                                   loader: 'css-loader'
                               }
                           ]
                       }
                   ]
               }
           };
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        style-loader 需要写在css-loader前面
      2. style-loader/url
        1. 使用style-loader的webpack.config.js的地方 直接使用style-loader/url,样式文件可以直接link进来。但是这种使用还需要一个file-loader. 之前使用css-loader的地方,要改为使用file-loader 这种情况下的打包,会直接打包出来一个单独的css文件。不常用。因为不能处理多个样式。若处理多个样式,则需要多个link标签
      3. style-loader/useable
        1. 可以在style-loader中控制是否插入到页面中去
        module: {
                rules: [
                    {
                        test: /\.css$/,
                        use: [
                            {
                                loader: 'style-loader/useable'
                            },
                            {
                                loader: 'css-loader'
                            }
                        ]
                    }
                ]
            }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        pachage.json配置后。引入的样式文件会获得两个方法use()控制样式显示和unuse()控制样式不显示
        import base from './css.css'
        
        var flag = false;
        
        setInterval(function(){
            if(flag) {
                base.unuse();
            } else {
                base.use();
            }
            flag = !flag
        }, 500);
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
      4. style-loader的配置
        1. options
          1. insertAt (插入位置)
          2. insertInto (插入到具体的dom)
          3. singleton (是否使用一个style标签)
          4. transform (转化,在浏览器环境下,插入页面前)
          5. package.json
            module.export = {
                module: {
                        rules: [
                            {
                                test: /\.css$/,
                                use: [
                                    {
                                        loader: 'style-loader',
                                        options: {
                                            insertInto: '#app',
                                            singleton: true,
                                            transform: './css.transform.js' //css变形的路径。相对于config.js的路径
                                        }
                                    },
                                    {
                                        loader: "css-loader"
                                    }
                                ]
                            }
                        ]
                    }
            }
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
          6. css.transform.js
              module.exports =function(css) {
                  console.log(loading);
                  console.log(css);
                  console.log(window.innerHeight);
                  return css;
              };
            
            1
            2
            3
            4
            5
            6
            css.transform.js文件可以拿到所有的css样式
    2. css-loader
      1. css-loader 在JS中直接require加载css样式文件
        1. options:
          1. alias(解析别名,路径映射)
          2. importLoader(支持@import,取决于css-loader后面是否有其他的loader才有用)
          3. Minimize(是否压缩样式文件,职位true和false)
          4. modules(是否启用css-modules)
        2. css-modules
          1. :local(本地样式)
          2. :global(定义全局样式)
          3. compose(继承样式)
          4. compose ... from (从某一个文件里引入样式)
      less/sass
    3. less/sass
      1. 安装
        yarn add less-loader less --save-dev
        yarn add sass-loader node-sass --save-dev
        
        1
        2
      2. 配置
        module: {
            rules: [
                {
                    test: /\.less$/,
                    use: [
                        {
                            loader: 'style-loader',
                            options: {
                                singleton: true,
                                transform: './css.transform.js'
                            }
                        },
                        {
                            loader: 'css-loader',
                            options: {
                                minimize: true,
                                modules: true,
                                localIdentName: '[path][name]_[local]_[hash:base64:5]'
                            },
                        },
                        {
                            loader: 'less-loader'
                        }
                    ]
                }
            ]
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
      提取css
    4. 提取css
      1. extract-loader
      2. ExtractTextWebpackPlugin
        1. 安装
        yarn add extract-text-webpack-plugin --save-dev
        
        1
        1. 使用
          1. webpack.config.js
          let path = require('path');
          let ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
             
          module.exports = {
              entry: {
                    app: './app.js'
                },
             
                output: {
                    path: path.resolve(__dirname, 'dist'),
                    filename: '[name].bundle.js',
                    publicPath: './dist/',
                    chunkFilename: '[name].bundle.js',
                },
             
                module: {
                    rules: [
                        {
                            test: /\.less$/,
                            use: ExtractTextWebpackPlugin.extract({
                                fallback: {
                                    loader: 'style-loader',
                                    options: {
                                        singleton: true,
                                        transform: './css.transform.js'
                                    }
                                },
                               use: [
                                    {
                                        loader: 'css-loader',
                                        options: {
                                            minimize: true,
                                            modules: true,
                                            localIdentName: '[path][name]_[local]_[hash:base64:5]'
                                        },
                                    },
                                    {
                                        loader: 'less-loader'
                                    }
                                ]
                            })
                        }
                    ]
                },
             
              plugins: [
                  new ExtractTextWebpackPlugin({
                      filename: '[name].min.css',
                      allChunks: false
                  })
              ]
          };
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          1. app.js
          import base from './css/base.less'
          import common from './css/common.less'
          
          let app = document.getElementById('app');
          app.innerHTML = `<div class="${base.box}"></div>`;
          
          //实现异步加载a模块
          import(
              /* webpackChunkName: 'a' */
              './components/a'
              ).then(function(a) {
                  console.log(a)
          });
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13

文件处理

图片处理
  1. 图片处理
    1. css中引入的图片
      1. file-loader
        1. 安装
          yarn add file-loader --save
          
          1
        2. 配置
          module.exports = {
              entry: {
                  app: './app.ts'
              },
              output: {
                  filename: '[name].[hash:5].js'
              },
              module:{
                  rules:[
                      {
                          test: /\.(png|jpg|jpeg|gif)?$/,
                          use:{
                              loader: 'file-loader',
                              options: {
                                 publicPath:''//根目录
                                 outputPath:'filename/', //指定目录下
                                 useRelativePath: true //每个文件生成一个相对url的context                                    }
                          },
                      }
                  ]
              }
          }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
    2. 自动合并成雪碧图
      1. postcss-sprites
        1. 安装
          yarn add postcss-sprites --save
          
          1
        2. 配置
          module.exports = {
              entry: {
                  app: './app.ts'
              },
              output: {
                  filename: '[name].[hash:5].js'
              },
              module:{
                  rules:[
                      {
                          test: /\.(png|jpg|jpeg|gif)?$/,
                          use:{
                              loader: 'post-loader'
                              options: {
                                      ident: 'postcss',
                                      plugins: [
                                          //打包生成雪碧图的配置
                                          require('postcss-sprites')({
                                              //雪碧图打包后的地址
                              				spritePath: 'dist/assets/imgs/',
                                              //适应高分辨率视口 // 2倍图等
                                              retina: true
                                          }),
                                          require('postcss-cssnext')()
                                      ]
                                  }
                          },
                      }
                      //修改雪碧图的名字
                      {        
                          loader: 'url-loader',
                          options: {
                              name: '[name]-[hash:5]-min.[ext]', //ext 是文件后缀
                              limit: 200,
                              //publicPath: '',
                              //outputPath: '',
                              //将打包生成的文件关联原文件夹
                              useRelativePath: true
                          }
                      },
                  ]
              }
          }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
    3. 压缩图片
      1. img-loader
        1. 安装
          yarn add img-loader --save
          
          1
        2. 配置
          module.exports = {
              entry: {
                  app: './app.ts'
              },
              output: {
                  filename: '[name].[hash:5].js'
              },
              module:{
                  rules:[
                      {
                          test: /\.(png|jpg|jpeg|gif)?$/,
                          use:{
                              loader: 'img-loader',
                              options: {
                                  quality:100
                              }
                          },
                      }
                  ]
              }
          }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
    4. base64编码
      1. url-loader
        1. 安装
          yarn add url-loader --save
          
          1
        2. 配置
          module.exports = {
              entry: {
                  app: './app.ts'
              },
              output: {
                  filename: '[name].[hash:5].js'
              },
              module:{
                  rules:[
                      {
                          test: /\.(png|jpg|jpeg|gif)?$/,
                          use:{
                              loader: 'url-loader',
                              options: {
                              //当图片大小小于限制时会自动转成 base64 码,不生成图片
                                  limit: 800
                              }
                          },
                      }
                  ]
              }
          }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
字体文件
  1. 字体文件
    1. 配置
      module.exports = {
          entry: {
              app: './app.ts'
          },
          output: {
              filename: '[name].[hash:5].js'
          },
          module:{
              rules:[
                  {
                      {
                          test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                          loader: 'url-loader',
                          options: {
                              name:'[name]-[hash:5].[ext]'
                              limit: 1000,
                              publicPath:''
                              outputPath:'filename/',
                              useRelativePath: true 
                           }
                      }
                  }
              ]
          }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
第三方js库
  1. 第三方js库
    1. script标签引入可以直接使用
    2. ProvidePlugin
      1. 安装
        yarn add jquery --save
        
        1
      2. 配置
        new webpack.ProvidePlugin({
           $: 'jquery',
           jQuery: 'jquery'
         })
        
        1
        2
        3
        4
    3. imports-loader
      1. 安装
        yarn add imports-loader --save
        
        1
      2. 配置
        module.exports = {
            module: {
                rules: [
                    {
                        test: path.resove(_dirbane,'src/app.js'),
                        use: [
                           {
                               loader:'imports-loader',
                               options:{
                                    $: 'jquery',
                               }
                           }   
                        ]
                    }
                ]
            }
        };
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
HTML in webpack
  1. HTML in webpack
    1. html-webpack-plugin
      1. 安装
        yarn add html-webpack-plugin --save-dev
        
        1
      2. options 配置项
        1. template(模板文件,可以是html,ejs等结尾,默认为index.html)
        2. filename(文件名,默认为index.html)
        3. minify(是否压缩)
        4. chunks(指定有哪几个excludeChunks加入到页面中去,默认会选所有)
        5. inject(是否让html-webpack-plugin将想要的css样式插入到页面中,默认为true)
        6. excludeChunks(排除的chunks)
      3. 配置
        1. webpack.config.js
          var HtmlWebpackPlugin = require('html-webpack-plugin');
          var path = require('path');
          
          module.exports = {
            entry: 'index.js',
            output: {
              title: '首页', // (生成html文件的标题)
              favicon: './favicon.ico',// (icon的url)
              path: path.resolve(__dirname, './dist'),
              template: './src/index.html', // (模板文件,可以是 html,jade,ejs,hbs等等,如果你设置的 title 和 filename于模板中发生了冲突,那么以你的title 和 filename 的配置值为准。)
              filename: 'index_bundle.html', // (打包后生成html文件的名字)
              inject:false,  /*  注入选项。有四个选项值 true, body, head, false
                              *  true:默认值,script标签位于html文件的 body 底部
                              *  body:script标签位于html文件的 body 底部(同 true)
                              *  head:script标签位于head标签内
                              *  false:不插入生成的js文件,只是单纯的生成一个 html文件
                             */
              minify:{
                    collapseWhitespace: true, // (清理html中的空格、换行符。默认值false) 
                    removeComments: true, // (清理html中的注释,默认值false)
                    removeRedundantAttributes: true, // (删除多余的属性,默认值false) 
                    removeScriptTypeAttributes: true, // (删除script的类型属性,在h5下面script的type默认值:text/javascript 默认值false) 
                    removeStyleLinkTypeAttributes: true, // (删除style的类型属性,默认值false) 
                    useShortDoctype: true, // (使用短的文档类型,将文档转化成html5,默认false)
                    minifyCSS: true, // (压缩html内的css。默认值false)
                    minifyJS: true, // (压缩html内的js。默认值false)
                    caseSensitive: true, // (是否对大小写敏感,true为大小写敏感,false则大小写不敏感,会全部转为小写)   
              },
              hash: true, // (默认false。当设置为true时,给注入的js生成一个hash值(XXX.js?22b9692e22e7be37b57e),以防止缓存)
              cache: true, // (默认true。内容变化的时候生成一个新的文件)
              showErrors: true, // (默认true。如果webpack编译出现错误,webpack会将错误信息包裹在一个 pre 标签内,也就是显示错误信息,方便定位错误)
              chunks: ['index'], // (编译后的html引入的js入口文件)
              excludeChunks: ['home'] // (同chuncks相反,是编译后的html排除的js入口文件) 
            },
            plugins: [new HtmlWebpackPlugin()]
          };
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
HTML-loader
  1. HTML-loader
    1. 安装
      yarn add  -D html-loader
      
      1
    2. 配置
      1. options
      2. webpack.config.js
        {
          test: /\.(html)$/,
          use: {
            loader: 'html-loader',
            options: {
              attrs: [':data-src'] // attrs 默认值:data-src
            }
          }
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9

配合优化

  1. 配合优化
    1. 提前载入webpack加载代码
      1. inline-manifest-webpack-plugin (将webpack生成的代码插入到html中,和html-loader配合时会有bug)
      2. html-webpack-inline-chunk-plugin (将选择的chunk插入到html中)
        1. 安装html-webpack-inline-chunk-plugin
          yarn add html-webpack-inline-chunk-plugin --save-dev
          
          1
        2. 安装babel
          yarn add babel-core babel-loader baber-preset-env --save
          
          1
        3. 配置
          const HtmlWebpackInlineChunkPlugin=require('html-webpack-inline-chunk-plugin')
          
          module.exports = {
              plugins:[
                     new HtmlWebpackInlineChunkPlugin({
                            inlineChunks:['manifest']
                     })
                     new webpack.optimize.CommonsChunkPlugin({
                            //自己生产的公共代码取名为manifest
                            name:'manifest'
                     })
                 ]
            //使用的时候要注意不要和Htmlwebpackplugin的chunk起冲突
          }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14

开发环境

webpack Watch Mode

clean-webpack-plugin
  1. clean-webpack-plugin
    1. 安装clean-webpack-plugin
      yarn add clean-webpack-plugin -D
      
      1
    2. 配置
      const CleanWebpackPlugin = require('clean-webpack-plugin');
      
      module.exports = {
        plugins: [
         new CleanWebpackPlugin(),
        ],
        output: {
          filename: '[name].bundle.js',
          path: path.resolve(__dirname, 'dist')
        }
      };
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
    3. 执行 webpack -watch --progress --display-reasons --color
webpack-dev-server
  1. webpack-dev-server
    1. 功能
      1. live reloading (刷新浏览器)
      2. 路径重定向
      3. 浏览器中显示编译错误
      4. https
      5. 接口代理
      6. 热更新(不在刷新浏览器的情况下,进行热更新)
    2. 安装
      yarn add webpack-dev-server --save-dev
      
      1
    3. devServer
      1. inline (页面打包状态,默认为true)
      2. contentBase (提供内容的路径, 如果内容是静态的需要配置,默认是当前目录)
      3. port (监听端口)
      4. historyApiFallback (在使用html5的history api 的时候,如果访问某一个路径不会导致404,去指定一个重定向规则)
      5. https (指定为true后,就会本地生产证书)
      6. proxy (远程接口的代理)
      7. hot (打开模块热更新,在某一个时间代码替换)
      8. openpage (最先打开的页面,初始页面位置)
      9. lazy (不编译所有的页面, 只会在打开某个页面的时候才会去编译 ,设置为懒模式 在多页面开发非常有用)
      10. overlay (当页面出现错误的时候, 出现一个页面遮罩错误提示)
    4. 配置
      1. package.json
        "scripts": {
           "server":"webpacki-dev-server --open"
        }
        
        1
        2
        3
      2. webpack.config.js
         module.exports={
            entry:{},
            output:{},
            plugins:[],
            modules:{},
            devServer:{
               port:9001,
               historyApiFallback:{
                  rewrites:[
                     {
                        from:/^\([a-zA-Z0-9]+\/?)([a-zA-Z0-9]+)/, //规则
                        to:function(context){
                           retrun '/'+context.match[1]+  context.match[2]+'.html'
                        }
                     }
                  ]
               }
            }
         }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
Proxy
  1. Proxy
    1. http-proxy-middleware
      1. options
        1. target (指定代理的地址)
        2. changeOrigin (是否允许跨域,默认为false)
        3. headers (增加请求https请求头)
        4. logLevel (帮助调试的, 在控制台命令行中显示代理情况,代理信息)
        5. pathRewrite (重定向接口请求)
      2. 配置
        1. ajax
           $.get('/comments/show',{
               id:'4193566666',
               page:1
           },function(data){
               console.log(data)
           })
          
          1
          2
          3
          4
          5
          6
        2. webpack.config.js
           module.exports={
              entry:{},
              output:{},
              plugins:[],
              modules:{},
              devServer:{
                 port:9001,
                 historyApiFallback:{
                    rewrites:[
                       {
                          from:/^\([a-zA-Z0-9]+\/?)([a-zA-Z0-9]+)/, //规则
                          to:function(context){
                             retrun '/'+context.match[1]+  context.match[2]+'.html'
                          }
                       }
                    ]
                 },
                 proxy:{
                    '/':{
                       target:'https://m.weibo.cn',
                       changeOrigin:true, // 允许跨域
                       logLevel :'debug', // 控制台输出从发送请求到响应的详细信息
                       pathRewrite :{
                           '^/comments':'/api/comments'
                        },
                        headers:{
                           'Cookie':'真实的cookie,可以从浏览器控制台获取'
                        }
                    }
                 }
              }
           }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
模块热更新
  1. Hot Module Replacement (模块热更新)
    1. 好处
      1. 保持应用数据状态
      2. 节省调试时间
      3. 调试样式更快
    2. 配置
      1. webpack.config.js
           module.exports={
              entry:{},
              output:{},
              plugins:[
                 new webpack.HotModuleReplacementPlugin(),
                 new webpack.NameMoudlesPlugin()
              ],
              modules:{},
              devServer:{
                 port:9001,
                 historyApiFallback:{
                    rewrites:[
                       {
                          from:/^\([a-zA-Z0-9]+\/?)([a-zA-Z0-9]+)/,
                          to:function(context){
                             retrun '/'+context.match[1]+  context.match[2]+'.html'
                          }
                       }
                    ]
                 },
                 proxy:{
                    '/':{
                       target:'https://m.weibo.cn',
                       changeOrigin:true,
                       logLevel :'debug',
                        pathRewrite :{
                           '^/comments':'/api/comments'
                        },
                        headers:{
                           'Cookie':'....'
                        }
                    }
                 },
                 hot:true,  //热更新启用
                 hotOnly:true //不刷新浏览器
              }
           }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
调试
  1. source map 调试
    1. 开启 source map
      1. 通过配置的参数Devtool开启
        1. Development(有七个值,开发环境下使用的有五个)
          1. eval
          2. eval-source-map
          3. cheap-eval-source-map
          4. cheap-modlue-eval-source-map
          5. cheap-module-source-map
        2. prduction(生产环境下,值有三个)
          1. source-map
          2. hidden-source-map
          3. nosource-source-map
      2. 通过webpack.SourceMapDevToolPlugin
      3. 通过webapck.EvakSourceMapDevToolPlugin
    2. 配置
      1. webpack.config.js
           module.exports={
              entry:{},
              output:{},
              plugins:[
                 new webpack.HotModuleReplacementPlugin(),
                 new webpack.NameMoudlesPlugin()
              ],
              modules:{},
              devServer:{
                 port:9001,
                 historyApiFallback:{
                    rewrites:[
                       {
                          from:/^\([a-zA-Z0-9]+\/?)([a-zA-Z0-9]+)/,
                          to:function(context){
                             retrun '/'+context.match[1]+  context.match[2]+'.html'
                          }
                       }
                    ]
                 },
                 proxy:{
                    '/':{
                       target:'https://m.weibo.cn',
                       changeOrigin:true,
                       logLevel :'debug',
                        pathRewrite :{
                           '^/comments':'/api/comments'
                        },
                        headers:{
                           'Cookie':'....'
                        }
                    }
                 },
                 hot:true,  //热更新启用
                 hotOnly:true //不刷新浏览器
                 devtool:'cheap-module-source-map'
              }
           }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
    3. cssloader 加sourcemap : true 必须到options 里面的
    4. singleton: true, // 使用一个style标签 singleton必须为false
通过Eslint检查代码格式
  1. Eslint
    1. 安装
      yarn add eslint eslint-loader eslint-plugin-htm eslint-friendly-formatter -D
      
      1
      1. eslint-loader (解析器)
        1. options.failOnWarning (默认为false,当设置为false,代码出现错误,不会通过编译)
        2. options.failOnError (默认为false,当设置为false,代码出现错误,不会通过编译)
        3. options.formatter (设置第三方友好提示的formatter)
        4. options.outputReport (输出代码报告)
      2. eslint-plugin-html (检查html里的js)
      3. eslint-friendly-formatter (报错时输出格式)
    2. 配置eslint
      1. 根目录下新建.eslintrc.js文件
        module.exports={
            root:true,
            extends:'standard',  // 使用标准
            plugins:[
                //安装之前的html 插件
                'html'
            ],
            //定义环境 
            env:{
                // 浏览器
                brower:true,
                // node
                node:true
            },
            //定义规则
            rulse:{
                  indent: ['error',4] // 缩进为4 前面的是这条规则的重要性。可以是warning/error
                  'eol-last':['error','error'] // 不需要换行
               },
            //把不允许的全局变量设为允许
            globals:{
                $:true
            }
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
      2. webpack.config.js
        rules:[
            {
                test:/\.js$/,
                //eslint检测的文件
                include:[path.resolve(__dirname, 'src')],
                //eslint不检测文件
                exclude:[path.resolve__dirname,'src/libs')]
                use:[
                    {
                        loader:'babel-loader',
                        options:{
                            presets:[''env']
                        }
                    },
                    {
                        loader:'eslint-loader',
                        options:{
                            formatter:require('eslint-friendly-formatter')
                        }
                    }
                ]
            }
        ]
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
开发环境和生产环境
  1. 生产环境
    1. 提取公共代码
    2. 压缩混淆
    3. 文件压缩
    4. 去除无用代码
  2. 开发环境
  3. 开发环境和生产环境的共同点
    1. 同样的入口
    2. 同样的代码loader处理
    3. 同样的解析配置
  4. wenpack-merge
    1. wenpack.dev.conf.js // 开发环境
    2. webpack.prod.conf.js // 生产环境
    3. webpack.common.conf.js //开发生产环节都会 用到
  5. build配置项
    1. webpack.common.conf.js
      const productionConfig = require('./webpack.prod.conf');
      const developmentConfig = require('./webpack.dev.conf');
      
      const merge = require('webpack-merge');
      const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
      
      const path = require('path');
      const Webpack = require('webpack');
      const HtmlWebpackPlugin = require('html-webpack-plugin');
      
      const generateConfig = env => {
          /*插件部分*/
          //提取代码的公用插件
          const extractLess = new ExtractTextWebpackPlugin({
              filename: (getPath) => {
                  return getPath('css/[name].min.[hash:5].css').replace('css/js', 'css');
              },
              allChunks: false
          });
      
      
          /*loader部分*/
          // 打包编译JS
          const scriptLoader = [
              {
                  loader: 'babel-loader'
              }
          ];
          //打包编译css
          const cssLoaders = [
              {
                  loader: 'css-loader',
                  options: {
                      minimize: env === 'production',
                      // modules: true,
                      localIdentName: '[path][name]_[local]_[hash:base64:5]'
                  },
              },
              {
                  loader: 'postcss-loader',
                  options: {
                      ident: 'postcss',
                      sourceMap: env === 'development',
                      plugins: [
                          require('postcss-cssnext')()
                      ].concat(
                          env === 'production' ?
                              require('postcss-sprites')({
                                  spritePath: './dist/assets/img/sprites',
                                  retina: true
                              }) : []
                      )
                  }
              },
              {
                  loader: 'less-loader'
              }
          ];
          //打包编译样式
          const styleLoader = env === 'production'
              ? ExtractTextWebpackPlugin.extract({
                  fallback: {
                      loader: 'style-loader',
                      options: {
                          singleton: true,
                          transform: './css.transform.js'
                      }
                  },
                  use: cssLoaders
              }) : [{
                  loader: 'style-loader',
                  options: {
                      // singleton: true,
                      transform: './css.transform.js',
                      sourceMap: true
                  }
              }].concat(cssLoaders);
          // 打包编译文件
          const fileLoader = env === 'development' ? [
              {
                  loader: 'file-loader',
                  options: {
                      options: {
                          outputPath: './img/',
                      }
                  }
              }
          ] : [
              {
                  loader: 'url-loader',
                  options: {
                      limit: 1024 * 2,
                      fallback: {
                          loader: 'file-loader',
                          options: {
                              outputPath: './img/',
                          }
                      }
                  }
              }
          ];
      
          return {
              entry: {
                  app: './src/app.js'
              },
      
              output: {
                  path: path.resolve(__dirname, '../dist'),
                  filename: 'js/[name].bundle.[hash:5].js',
                  publicPath: '/',
                  chunkFilename: '[name].bundle.[hash:5].js',              //动态打包文件名
              },
      
              resolve: {
                  alias: {
                      jquery$: path.resolve(__dirname, '../src/lib/jquery.min.js')                  // 之所以要用jquery$ ,表示这是一个文件而已;
                  }
              },
      
              module: {
                  rules: [
                      {
                          test: /\.js$/,
                          include: [path.resolve(__dirname, '../src')],
                          exclude: [path.resolve(__dirname, '../src/lib/jquery.min.js')],
                          use: scriptLoader
                      },
                      {
                          test: /\.less$/,
      
                          use: styleLoader
                      },
                      {
                          test: /\.(png|jpg|jpeg|gif)$/,
                          use: fileLoader.concat(
                              env === 'production' ?
                                  {
                                      loader: 'img-loader'
                                  }: []
                          )
                      },
                      {
                          test: path.resolve(__dirname, 'src/app.js'),
                          use: [
                              {
                                  loader: 'imports-loader',
                                  options: {
                                      $: 'jquery'
                                  }
                              }
                          ]
                      },
                      {
                          test: /\.html$/,
                          use: [
                              {
                                  loader: 'html-loader',
                                  options: {
                                      attrs: ['img:src', 'img:data-src']
                                  }
                              }
                          ]
                      },
                      {
                          test: /\.(eot|woff2|woff|ttf|svg)$/,
                          use: [
                              {
                                  loader: 'url-loader',
                                  options: {
                                      limit: 1024 * 50,
                                      fallback: {
                                          loader: 'file-loader',
                                          options: {
                                              // useRelativePath: true,
                                              publicPath: '../fonts',
                                              outputPath: 'fonts',
                                          }
                                      }
                                  }
                              }
                          ]
                      }
                  ]
              },
      
              plugins: [
                  extractLess,
      
                  new HtmlWebpackPlugin({
                      filename: 'index.html',
                      template: './index.html',
                      chunks: ['app'],
                      minify: {
                          collapseWhitespace: false                //祛除空格
                      }
                  }),
      
                  new Webpack.ProvidePlugin({
                      $: 'jquery'
                  }),
              ]
          }
      };
      
      module.exports = env => {
          let config = env === 'production' ? productionConfig : developmentConfig;
      
          return merge(generateConfig(env), config)
      };
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      153
      154
      155
      156
      157
      158
      159
      160
      161
      162
      163
      164
      165
      166
      167
      168
      169
      170
      171
      172
      173
      174
      175
      176
      177
      178
      179
      180
      181
      182
      183
      184
      185
      186
      187
      188
      189
      190
      191
      192
      193
      194
      195
      196
      197
      198
      199
      200
      201
      202
      203
      204
      205
      206
      207
      208
      209
      210
    2. webpack.dev.conf.js
      const Webpack = require('webpack');
      const Jarvis = require('webpack-jarvis');
      
      module.exports = {
          devtool: "cheap-module-source-map",
      
          devServer: {
              port: 3000,
              proxy: {
                  '/': {
                      target: 'http://localhost:3002',
                      changeOrigin: true,
                      logLevel: 'debug',
                      pathRewrite: {
                          '': '/api/'
                      }
                  }
              },
              hot: true,
              hotOnly: true,
          },
      
          plugins: [
      
              new Webpack.HotModuleReplacementPlugin(),
      
              new Webpack.NamedModulesPlugin(),
      
              new Jarvis({
                  port: 3001
              }),
          ]
      };
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
    3. webpack.prod.conf.js
      const path = require('path');
      const Webpack = require('webpack');
      const PurifyCSS = require('purifycss-webpack');
      const glob = require('glob-all');
      const HtmlInlineChunkPlugin = require('html-webpack-inline-chunk-plugin');
      const CleanWebpackPlugin = require('clean-webpack-plugin');
      
      module.exports = {
          plugins: [
              new PurifyCSS({
                  paths: glob.sync([
                      path.join(__dirname, './*.html'),
                      path.join(__dirname, './src/*.js')
                  ]),
              }),
      
      
              new Webpack.optimize.CommonsChunkPlugin({
                  name: 'manifest'
              }),
      
              new HtmlInlineChunkPlugin({
                  inlineChunks: ['manifest']
              }),
      
              new Webpack.optimize.UglifyJsPlugin(),
      
              new CleanWebpackPlugin(['dist']),
          ]
      };
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
    4. package.json
        "scripts": {
          "server": "webpack-dev-server --env development --config build/webpack.common.conf.js",
          "build": "webpack --env production --config build/webpack.common.conf.js",
        },
      
      1
      2
      3
      4
使用middleware搭建开发环境
  1. 使用middleware搭建开发环境
    1. 安装middleware
      yarn add  express opn webpack-dev-middleware webpack-hot-middleware http-proxy-middleware connect-history-api-fallback --save-dev
      
      1

TOC