进击webpack4 (优化篇)

进击webpack 4 (基本篇一)
进击webpack4 (基本篇二:设置 一)
进击webpack4 (基本篇三:设置 二)

不剖析不依靠第三方模块的模块

noParse

有一些第三方模块,它本身不依靠于其他模块,比方jquery,lodash,不去编译这些库,会使得webpack打包越发疾速
noParse是个正则或许包括正则的数组 RegExp | [RegExp]

module:{
        noParse:/jquery/, //不去剖析jquery
        rules:[
            //...
        ]
    },
--------------------- 

疏忽某些库内的第三方模块

ignorePlugin

以moment这个时刻库为例, 导入moment的同时, moment会引入本身依靠的语言包,这些语言包其中有部份是我们不须要用到的,moment内部代码

《进击webpack4 (优化篇)》

  plugins: [
      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
    ],

2个参数代表的意义是:

当婚配到moment这个库的时刻 引入moment而且疏忽moment内里婚配到locale的库

这个时刻我们假如想要本身须要的locale 需在main.js手动引入

import 'moment/locale/zh-cn'

动态链接库

另起一个webpack.config.dll.js 特地用来天生动态链接库

//webpack.config.dll.js

const path=require('path');
const webpack=require('webpack');
module.exports={
    mode:'development',
    entry: {
        react:['react','react-dom'],
        jquery:['jquery']
    },// 把 React 相干模块的放到一个零丁的动态链接库
    output: {
        path: path.resolve(__dirname,'dist'),// 输出的文件都放到 dist 目录下
        filename: '[name].dll.js',//输出的动态链接库的文件称号,[name] 代表当前动态链接库的称号
        library: '_dll_[name]',//寄存动态链接库的全局变量称号,比方对应 react 来讲就是 _dll_react
    },
    plugins: [
        new webpack.DllPlugin({
            // 动态链接库的全局变量称号,须要和 output.library 中保持一致
            // 该字段的值也就是输出的 mainfest.json 文件 中 name 字段的值
            // 比方 react.manifest.json 中就有 "name": "_dll_react"
            name: '_dll_[name]',
            // 形貌动态链接库的 manifest.json 文件输出时的文件称号
            path: path.join(__dirname, 'dist', '[name].mainfest.json')
        })
    ]
}
//打包
npx webpack --config webpack.config.dll.js 

如许会在dist天生

《进击webpack4 (优化篇)》

然后在webpack.config.js里

const webpack= require('webpack')
plugins: [
  new webpack.DllReferencePlugin({
    manifest:require('./dist/react.mainfest.json')
  }),
  new webpack.DllReferencePlugin({
    manifest:require('./dist/jquery.mainfest.json')
  })
]

这里它会从mainfest.json寻觅name 然后依据它的标识找到响应内容, dll.js就是打包出来后的动态链接库

《进击webpack4 (优化篇)》

然后在html模板文件里引入

<script src="./jquery.dll.js"></script>
<script src="./react.dll.js"></script>

假如你在main.jsimport React from 'react',他会首先找动态链接库, 找不到才会实行打包

《进击webpack4 (优化篇)》
《进击webpack4 (优化篇)》

注:运用react须要设置好rule


{
test:/\.js/,
    use:{
        loader:'babel-loader',
        options:{
            presets:[
                '@babel/preset-env',
                '@babel/preset-react'
            ]
        }
    }
},

开启多历程打包

npm i happypack -D

假如一个项目代码麋集,读写操纵频仍,happypack 就能让Webpack把使命剖析给多个子历程去并发的实行,子历程处置惩罚完后再把效果发送给主历程。

const HappyPack = require('happypack');
    rules: [
    {
        test: /\.js$/,
        // 把对 .js 文件的处置惩罚转交给 id 为 babel 的 HappyPack 实例
        use: ['happypack/loader?id=babel'],
        exclude: path.resolve(__dirname, 'node_modules'),
    },
    {
        test: /\.css$/,
        // 把对 .css 文件的处置惩罚转交给 id 为 css 的 HappyPack 实例
        use: ['happypack/loader?id=css']
    }
]
new Happypack({
            //ID是标识符的意义,ID用来代办当前的happypack是用来处置惩罚一类特定的文件的
            id: 'js',
            use: [{
                loader: 'babel-loader',
                //options=query都是向插件通报参数的
                options: {
                    presets: [["@babel/preset-env", { modules: false }], "@babel/preset-react"],
                    plugins: [
                        ["@babel/plugin-proposal-decorators", { "legacy": true }],
                        ["@babel/plugin-proposal-class-properties", { "loose": true }],
                    ]
                }
            }]
        }),
        new Happypack({
            //ID是标识符的意义,ID用来代办当前的happypack是用来处置惩罚一类特定的文件的
            id: 'css',
            use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
            threads: 4,//你要开启若干个子历程去处置惩罚这一范例的文件
            verbose: true//是不是要输出细致的日记 verbose
        })

注重:开启历程也须要时刻, 假如一个项目并非很庞杂, 推敲运用

不打包第三方库 运用cdn引入

module.exports = {
  //...
  externals: {
    jquery: 'jQuery'
  }
};

main.js 引入jquery 将不会打包 import jquery from 'jQuery'

html模板内引入jquery的cdn地点即可

只管运用es6的模块导入

webpack的tree-shaking本身能够分析出哪些没有运用到的代码能够剔除,条件是es6模块语法
scope-hosting能够提拔作用域 比方 var a = 1; var b = a ; console.log(b) 会编译成var b = 1; console.log(b)

提取大众代码

做这类操纵首先得是多页面

 entry:{
    home:['./src/index.js'],
    login:['./src/login.js']
}, // 进口文件
//home.js
import React from 'react'
import {render }from 'react-dom'
render(<h1>动态链接库</h1>,window.root)

//login.js
import React from 'react'
import {render }from 'react-dom'
render(<h1>动态链接库</h1>,window.root)
//webpack.config.js

optimization:{  // 优化
    splitChunks:{ //支解代码
        cacheGroups:{ // 缓存组
            common:{ // 大众的代码  平常是本身写的大众代码
                chunks:'initial',
                minSize:0,   
                minChunks: 2, //最少被援用2次的模块
                name: "common"
            },
            vendor:{  // 平常是第三方大众模块
                priority:1, // 由于实行是从上往下, 所以设置优先级比上面高  不然上面抽离的话第三方模块也被抽离了   
                test:/node_modules/ , //婚配node_modules下的大众代码,
                chunks:'initial',
                minSize:0,   
                minChunks: 2, //最少被援用2次的模块
                name: "vendor"
            }    
        }
    }
}

《进击webpack4 (优化篇)》

懒加载

这里拿vue举例

const Login = () => import(/* webpackChunkName: "login" */,"./login");
new VueRouter({
  routes: [{ path: "/login", component: Login }]
})

webpackChunkName虽然是解释, 然则webpack能辨认, 编译后这个组件临盆的名字就是login

可能会须要@babel/plugin-syntax-dynamic-import 才辨认

yarn add @babel/plugin-syntax-dynamic-import -D

详细设置看此文

热更新

devServer:{
  // 通知 DevServer 要开启模块热替代形式
  hot: true,      
}  

在vue中只需如许设置就能够了, vue本身帮我们做了设置

其他库中:

import React from 'react'
import {render} from 'react-dom'




render(<App/>, document.getElementById('root'));

if (module.hot) {
  // accept 函数的第一个参数指出当前文件接收哪些子模块的替代,这里示意只接收 ./AppComponent 这个子模块
  // 第2个参数用于在新的子模块加载终了后须要实行的逻辑
  module.hot.accept(['./App'], () => {
    // 新的 AppComponent 加载胜利后从新实行下组建衬着逻辑
    let App=require('./App').default;  
    render(<App/>, document.getElementById('root'));
  });
}
    原文作者:槐破梦
    原文地址: https://segmentfault.com/a/1190000018313064
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞