Skip to content

Latest commit

 

History

History
485 lines (453 loc) · 14.8 KB

webpack.md

File metadata and controls

485 lines (453 loc) · 14.8 KB
2019-06-20 补之前的笔记
  1. 新建webpack文件
  • 创建一个空文件
  • 敲命令
    npm init -y
    npm i webpack --save-dev
    npm i webpack-cli --save-dev
  • 在package.json里面配置命令
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  },
  • webpack4.0开始默认的打包入口是 ./src/index.js,所以需要在根目录下新建文件夹src然后新建文件index.js
  • 敲命令
    npm run build

就可以看到dist包了

2.生产模式和开发模式 通过在package.json里面配置运行命令,后面通过mode来区分生产模式和开发模式

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack --mode development",
    "build": "webpack --mode production"
  },
  • production mode(生产模式) 可以开箱即用地进行各种优化。 包括压缩,作用域提升,tree-shaking 等。
  • development mode(开发模式) 针对速度进行了优化,仅仅提供了一种不压缩的 bundle
  • 在 webpack4 中,可以在没有一行配置的情况下完成任务! 只需定义 –mode 参数即可获得所有内容!

3.配置打包入口和出口,再根目录新建webpack.config.js

const path = require('path')

module.exports = {
  entry: {
    app: '.src/index.js' // 需要打包的文件入口
  },
  output: {
    publicPath: __dirname + '/dist/', // js 引用的路径或者 CDN 地址
    path: path.resolve(__dirname, 'dist'), // 打包文件的输出目录
    filename: 'bundle.js' // 打包后生产的 js 文件
  }
}

  • path.resolve() 方法会把一个路径或路径片段的序列解析为一个绝对路径。从盘符开始
  • __dirname: 当前项目的名称
  • 安装配置后每次需要把dist包已存在内容清掉,然后再去打包,需要安装下面的插件
npm install clean-webpack-plugin --save-dev

  • webpack.config.js修改配置
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
module.exports = {
    plugins: [
        new CleanWebpackPlugin() // 默认情况下,此插件将删除 webpack output.path目录中的所有文件,以及每次成功重建后所有未使用的 webpack 资产。
      ]
}

4.安装babel 用来编译ES6让浏览器认识

  • 安装
npm i @babel/core babel-loader @babel/preset-env @babel/plugin-transform-runtime --save-dev
npm i @babel/polyfill @babel/runtime
npm install --save core-js@3
  • 根目录下新建 .babelrc 内容如下
{
 "presets": [
   [
     "@babel/preset-env",
     {
       "useBuiltIns": "usage",
       "corejs": 3
     }
   ]
 ],
 "plugins": ["@babel/plugin-transform-runtime"]
}
  • webpack.config.js配置loader
    module.exports = {
        ......
        module: {
          rules: [
            {
              test: /\.js$/, // 使用正则来匹配 js 文件
              exclude: /node_modules/, // 排除依赖包文件夹
              use: {
                loader: 'babel-loader' // 使用 babel-loader
              }
            }
          ]
        }
    }
  • 根目录下新建 .browserslistrc文件,用于在不同前端工具之间共享目标浏览器版本和Node.js版本的配置
# 所支持的浏览器版本

> 1% # 全球使用情况统计选择的浏览器版本

last 2 version # 每个浏览器的最后两个版本

not ie <= 8 # 排除小于 ie8 以下的浏览器

5.代码分割 拆分出公共代码

  • 使用splitChunksPlugins,无须引入webpack自带模块之一
  • webpack.config.js配置
const CleanWebpackPlugin = require('clean-webpack-plugin')
module.exports = {
    ......
    output: {
        ......    
        filename: '[name].bundle.js', // 代码打包后的文件名
        chunkFilename: '[name].js' // 代码拆分后的文件名
    },
     optimization: {
             splitChunks: {
                 chunks: 'all', //分割所有代码,包括同步代码和异步代码
                 minSize: 30000,
                 maxSize: 0,
                 minChunks: 1,
                 maxAsyncRequests: 5,
                 maxInitialRequests: 3,
                 automaticNameDelimiter: '~',
                 name: true,
                 cacheGroups: {
                     vendors: {
                         test: /[\\/]node_modules[\\/]/, //只有 node_modules 引入的第三方库会被分割
                         priority: -10
                     },
                     default: {
                         minChunks: 2,
                         priority: -20,
                         reuseExistingChunk: true
                     }
                 }
             }
         },
}

  • webpack 代码分割的配置是这样的,比如我们要分割 jQuery 和 lodash 这样的第三方库,它会先经过 chunks、minSize、maxSize、minChunks 等等,满足条件后生成 jQuery 和 lodash 两个文件,然后放入 cacheGroup 中缓存着,再根据你在 cacheGroup 中配置的组来决定是将两个文件整合到一个文件打包,还是单独分开打包,比如上面代码中的 vendors,就是将 node_modules 中所有的第三方库都打包到 vendors.js 文件中
  • 如果还想继续分割,即单独打包文件就像下面这样利用test和priority(级别越高越会被先打包,就会被单独打包)
cacheGroups: {
  lodash: {
    name: 'lodash',
    test: /[\\/]node_modules[\\/]lodash[\\/]/,
    priority: 5  // 优先级要大于 vendors 不然会被打包进 vendors
  },
  vendors: {
    test: /[\\/]node_modules[\\/]/,
    priority: -10
  },
  default: {
    minChunks: 2,
    priority: -20,
    reuseExistingChunk: true
  }
}

6.Lazy Loading、Prefetching (懒加载与预读)

  • 不需要额外的配置就是尽量使用异步加载的方式,举个例子,页面有一个点击事件,就可以写成异步的加载到 页面(如写一个click.js文件,通过import加载进来,这个时候click.js不会跟其余同步代码一个加载,会在空闲的时候加载) ,这样可以提升页面响应速度
  • 与 prefetch 相比,Preload 指令有很多不同之处: Prefetch 会等待核心代码加载完之后,有空闲之后再去加载。Preload 会和核心的代码并行加载,还是不推荐

7.自动生成index.html

npm i html-webpack-plugin html-loader --save-dev
  • webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin') // 引入插件
module.exports = {
 output: {
        publicPath: './', // js 引用的路径或者 CDN 地址
        path: path.resolve(__dirname, 'dist'), // 打包文件的输出目录
        filename: '[name].bundle.js', // 代码打包后的文件名
        chunkFilename: '[name].js' // 代码拆分后的文件名
    },
  plugins: [
    new HtmlWebpackPlugin({
      // 打包输出HTML
      title: '自动生成 HTML',
      minify: {
        // 压缩 HTML 文件
        removeComments: true, // 移除 HTML 中的注释
        collapseWhitespace: true, // 删除空白符与换行符
        minifyCSS: true // 压缩内联 css
      },
      filename: 'index.html', // 生成后的文件名
      template: 'index.html' // 根据此模版生成 HTML 文件
    })
  ]
}

一定要修改out里面的publicpath因为项目后续部署到服务器,肯定是在服务器上读取这些资源

  • title: 打包后生成 html 的 title
  • filename:打包后的 html 文件名称
  • template:模板文件(例子源码中根目录下的 index.html)
  • chunks:和 entry 配置中相匹配,支持多页面、多入口
  • minify:压缩选项

8.处理css/scss文件

npm i css-loader style-loader --save-dev
  • 通过这两个loader会把css文件打包成js文件
  • 如果想单独打包成css文件需要安装插件
npm i mini-css-extract-plugin --save-dev
  • 还要安装压缩css的插件
npm install optimize-css-assets-webpack-plugin --save-dev
npm i node-sass sass-loader --save-dev

  • webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin') // 压缩 css
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/, // 针对 .css 后缀的文件设置 loader
        use: [
          {
            loader: MiniCssExtractPlugin.loader
          },
          'css-loader',
          'sass-loader' // 使用 sass-loader 将 scss 转为 css
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css'
    })
  ]
}


  • 但是mini-css-extract-plugin暂时还不支持热加载所以一般在生产环境使用,开发环境还是使用style-loader
  • rules.use的加载顺序是最后的最先执行
  • 添加浏览兼容前缀
npm install postcss-loader autoprefixer --save-dev

根目录下新建 postcss.config.js

module.exports = {
  plugins: [require('autoprefixer')]
}
module: {
  rules: [
    {
      test: /\.(sa|sc|c)ss$/, // 针对 .sass .scss 或者 .css 后缀的文件设置 loader
      use: [
        {
          loader: MiniCssExtractPlugin.loader
        },
        'css-loader',
        'postcss-loader', // 使用 postcss 为 css 加上浏览器前缀
        'sass-loader' // 使用 sass-loader 将 scss 转为 css
      ]
    }
  ]
}

#####2019-06-18

  • webpack要点记录

9.js tree Shaking 对于非第三方应用,会自己进行优化,依据就是ES6的模块依赖系统 对于第三方插件,看看此插件是否符合ES模板系统规范,如loadsh正常引入是npm install lodash --save但是这个是没有摇树的 npm install lodash-es --save 这样安装就会摇树优化,这个时候我们在某个js组件里使用

import { chunk } from 'lodash-es'
console.log(chunk([1, 2, 3], 2))

他就只会打包我们用到的ckunk方法,而不会打包所有的lodsh

10.css tree shaking

  • 安装依赖
npm install --save-dev mini-css-extract-plugin
npm i glob-all purify-css purifycss-webpack --save-dev
  • webpack.config.js
    const PurifyCSS = require('purifycss-webpack')
    const glob = require('glob-all')
    module.exports = {
    module: {
            rules: [
                ......
                {
                    test: /\.css$/, // 针对 .css 后缀的文件设置 loader
                    use: [
                        {
                            loader: MiniCssExtractPlugin.loader
                        },
                        'css-loader']
                }
            ]
        },
        plugins: [
                ......
                new MiniCssExtractPlugin({
                    filename: '[name].css',
                    chunkFilename: '[id].css'
                }),
                // 清除无用 css
                new PurifyCSS({
                    paths: glob.sync([
                        // 要做 CSS Tree Shaking 的路径文件
                        path.resolve(__dirname, './*.html'), // 请注意,我们同样需要对 html 文件进行 tree shaking
                        path.resolve(__dirname, './src/*.js')
                    ])
                })
            ],
    }

11.图片处理汇总

图片转成base64的优点

  • 无额外请求,
  • 对于极小或者极简单图片,
  • 可像单独图片一样使用,
  • 比如背景图片重复使用等,
  • 没有跨域问题,
  • 无需考虑缓存、文件头或者cookies问题

图片转成base64的缺点

  • 价则是 CSS 文件体积的增大,意味着 CRP 的阻塞
npm install url-loader file-loader --save-dev
//安装图片压缩插件
npm i image-webpack-loader --save-dev
module.exports = {
module: {
    rules: [
           {
                              loader: 'url-loader',
                              options: {
                                  name: '[name]-[hash:5].min.[ext]',
                                  limit: 1000, // size <= 1KB
                                  outputPath: 'images/'
                              }
                          },
                          // img-loader for zip img
                          {
                              loader: 'image-webpack-loader',
                              options: {
                                  // 压缩 jpg/jpeg 图片
                                  mozjpeg: {
                                      progressive: true,
                                      quality: 65 // 压缩率
                                  },
                                  // 压缩 png 图片
                                  pngquant: {
                                      quality: '65-90',
                                      speed: 4
                                  }
                              }
                          }
    ]
  }
}

12.字体文件处理 可以处理图标字体等特殊的字体

  • 只需要配置wepack文件就可以使用了 -webpack.config.js
    module.exports = {
    module: {
        rules: [
                {
                       test: /\.(eot|woff2?|ttf|svg)$/,
                       use: [
                         {
                           loader: 'url-loader',
                           options: {
                             name: '[name]-[hash:5].min.[ext]',
                             limit: 5000, // fonts file size <= 5KB, use 'base64'; else, output svg file
                             publicPath: 'fonts/',
                             outputPath: 'fonts/'
                           }
                         }
                       ]
                     }
        ]
      }
    }

13.开发模式与webpack-dev-server 开发中我们通常需要在本地启一个服务,以便于调试代码 -安装依赖

npm i webpack-dev-server --save-dev

-修改package.json dev启动命令

    {
      .....
      "scripts": {
        "dev": "webpack-dev-server --open",
        "build": "webpack --mode production"
      },
  • 修改webpack.config.js
    const webpack = require('webpack')
    module.exports = {
        mode: 'development', // 开发模式
        devtool: 'source-map', // 开启调试
      devServer: {
          contentBase: path.join(__dirname, 'dist'),
          port: 8000, // 本地服务器端口号
          hot: true, // 热重载
          overlay: true, // 如果代码出错,会在浏览器页面弹出“浮动层”。类似于 vue-cli 等脚手架
          proxy: {
            // 跨域代理转发
            '/comments': {
              target: 'https://m.weibo.cn',
              changeOrigin: true,
              logLevel: 'debug',
              headers: {
                Cookie: ''
              }
            }
          },
          historyApiFallback: {
            // HTML5 history模式
            rewrites: [{ from: /.*/, to: '/index.html' }]
          }
        },
      plugins: [
          new webpack.HotModuleReplacementPlugin(), // 热部署模块
          new webpack.NamedModulesPlugin(),
      ]
     
    }