多页面

重点entry 和 多个HtmlWebpackPlugin实例

  1. var path = require('path')
  2. var HtmlWebpackPlugin = require('html-webpack-plugin')
  3. module.exports = {
  4. mode:'development',
  5. entry:{
  6. about:'./src/about.js',
  7. home:'./src/home.js'
  8. },
  9. output:{
  10. filename:'[name].js',
  11. path:path.resolve(__dirname,'dist')
  12. },
  13. plugins:[
  14. new HtmlWebpackPlugin({
  15. template:'./index.html',
  16. filename:'home.html',
  17. chunks:['home']
  18. }),
  19. new HtmlWebpackPlugin({
  20. template:'./index.html',
  21. filename:'about.html',
  22. chunks:['about']
  23. })
  24. ]
  25. }

webpack 常见配置 - 图1

source-map

  1. // package.json
  2. devtool:'source-map',// 增加映射文件 会单独生成一个source-map文件
  3. devtool:'eval-source-map', // 也可以映射,但是不会生成source-map文件

清除包文件夹

  1. let { CleanWebpackPlugin } = require('clean-webpack-plugin');
  2. plugins: [
  3. ...
  4. new CleanWebpackPlugin(),
  5. ],

实时更新页面

  1. // webpack.config.json
  2. watch:true

跨域实现

配合webpack-dev-server

  1. // weback.config.json
  2. devServer: {
  3. proxy: {
  4. '/api': {
  5. target: 'http://localhost:3000',
  6. pathRewrite: { '/api': '' } // 路径重写 这里是把api给删除了
  7. }
  8. }
  9. }

resolve

如果想在页面中使用 bootstrap 的样式,一般会在入口文件中引入

  1. import 'bootstrap'

但是这样引入的 bootstrap 默认引入的是JS文件,所以页面的样式是不会生效的,下面是bootstrap的package的文件中main字段指定的路径

  1. "main": "dist/js/bootstrap",

如果想直接引入样式的话,可以在webpack的配置文件配置

  1. resolve: {
  2. // mainFields: ['style', 'main'] // 改变入口的文件字段
  3. alias: {
  4. 'bootstrap': 'bootstrap/dist/css/bootstrap.css'
  5. }
  6. }

dllPlugin 优化打包速度

也就是先把库打包出来, 并且生成一个manifest.json文件

1. 定义webpack.dll.config.js

  1. // webpack.dll.config.js
  2. module.exports = {
  3. entry: {
  4. // 定义程序中打包公共文件的入口文件vendor.js
  5. vendor: [path.resolve(src, 'js', 'vendor.js')],
  6. },
  7. plugins: [
  8. new webpack.DllPlugin({
  9. // manifest缓存文件的请求上下文(默认为webpack执行环境上下文)
  10. context: process.cwd(),
  11. // manifest.json文件的输出位置
  12. path: path.join(src, 'js', 'dll', '[name]-manifest.json'),
  13. // 定义打包的公共vendor文件对外暴露的函数名
  14. name: '[name]_[hash]'
  15. })
  16. ]
  17. }

1.1 打包公共文件

  1. // cross-env模块需要另外安装
  2. cross-env NODE_ENV=production webpack --config webpack.dll.config.js --colors --display-modules

2. 项目入口文件引入静态公共资源

  1. // main.js
  2. // 引入的公共模块如果在vendor中有被引用过,那么编译的时候直接使用静态文件vendor.dll.js
  3. import $ from 'jquery';
  4. console.log($)
  5. // import Vue from "Vue";
  6. // console.log(Vue)

引入方式并没有什么不同, 跟平时一样

3. 项目模板中引入公共静态文件

  1. <!-- index.html -->
  2. <script type="text/javascript" src="/src/js/dll/vendor.dll.js"></script>

4. 在webpack.config.js中关联引用

  1. // webpack.config.js
  2. module.exports = {
  3. entry: {
  4. // 项目入口文件
  5. 'app':path.resolve(src, 'js', 'main.js')
  6. },
  7. plugins: [
  8. // dllPlugin关联配置
  9. new webpack.DllReferencePlugin({
  10. // 跟dll.config里面DllPlugin的context一致
  11. context: process.cwd(),
  12. // dll过程生成的manifest文件
  13. manifest: require(path.join(src, 'js', "dll", "vendor-manifest.json"))
  14. })
  15. ]
  16. }

如此,在接下来的本地开发(dev过程)和线上构建过程,将不再重复静态公共资源的构建,极大地缩减我们的构建时间。

使用happypack多线程打包

  1. // webpack.config.js
  2. let Happypack = require('happypack');
  3. ...
  4. module: {
  5. rules: [
  6. {
  7. test: /\.js$/,
  8. exclude: /node_modules/,
  9. include: path.resolve('src'),
  10. use: 'Happypack/loader?id=js'
  11. },
  12. {
  13. test: /\.css$/,
  14. use: 'Happypack/loader?id=css'
  15. }
  16. ]
  17. },
  18. ...
  19. plugins: [
  20. new Happypack({
  21. id: 'css',
  22. use: ['style-loader', 'css-loader']
  23. }),
  24. new Happypack({
  25. id: 'js',
  26. use: [{
  27. loader: 'babel-loader',
  28. options: {
  29. presets: [
  30. '@babel/preset-env',
  31. '@babel/preset-react'
  32. ]
  33. }
  34. }]
  35. })
  36. ]

tree-shaking

webapck 在生产模式下自动启用 tree-shaking. 但是前提是使用es6 module引用的模块, 使用 common.js的模块tree-shaking 不起作用

抽取公共代码