资讯专栏INFORMATION COLUMN

进击webpack4 (优化篇)

isaced / 1332人阅读

摘要:进击基础篇一进击基础篇二配置一进击基础篇三配置二不解析不依赖第三方模块的模块有一些第三方模块,它本身不依赖于其他模块,比如,,不去编译这些库,会使得打包更加快速是个正则或者包含正则的数组不去解析忽略

进击webpack 4 (基础篇一)
进击webpack4 (基础篇二:配置 一)
进击webpack4 (基础篇三:配置 二)

不解析不依赖第三方模块的模块

noParse

有一些第三方模块,它本身不依赖于其他模块,比如jquery,lodash,不去编译这些库,会使得webpack打包更加快速
noParse是个正则或者包含正则的数组 RegExp | [RegExp]

module:{
        noParse:/jquery/, //不去解析jquery
        rules:[
            //...
        ]
    },
--------------------- 
忽略某些库内的第三方模块

ignorePlugin

以moment这个时间库为例, 导入moment的同时, moment会引入自身依赖的语言包,这些语言包其中有部分是我们不需要用到的,moment内部代码

  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生成

然后在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就是打包出来后的动态链接库

然后在html模板文件里引入


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


注:使用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(

动态链接库

,window.root) //login.js import React from "react" import {render }from "react-dom" render(

动态链接库

,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"
            }    
        }
    }
}

懒加载

这里拿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(, document.getElementById("root"));

if (module.hot) {
  // accept 函数的第一个参数指出当前文件接受哪些子模块的替换,这里表示只接受 ./AppComponent 这个子模块
  // 第2个参数用于在新的子模块加载完毕后需要执行的逻辑
  module.hot.accept(["./App"], () => {
    // 新的 AppComponent 加载成功后重新执行下组建渲染逻辑
    let App=require("./App").default;  
    render(, document.getElementById("root"));
  });
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102160.html

相关文章

  • 进击webpack4 (基础三:配置 二)

    摘要:多页面配置进击基础篇一进击基础篇二配置多页面配置多页面配置即是多入口需要写成对象形式,注意数组形式会变成多入口单页面,因为打包之后的会合并成一个入口文件出口不能写同一个文件用代替以上配置并不能多页面,还需要个模板,并且指明各自的代码块去生成 多页面配置 进击webpack 4 (基础篇一) 进击webpack4 (基础篇二:配置) ## 多页面配置 ## 多页面配置即是多入口 entr...

    sourcenode 评论0 收藏0
  • 进击webpack4 (基础:配置 一)

    摘要:进入入口起点后,会找出有哪些模块和库是入口起点直接和间接依赖的。用于对模块的源代码进行转换。指定生产还是开发入口文件打包后的文件名这里需指定一个绝对路径我们需要的模块去解析路径包含一系列的规则是一个具有属性的对象。 前文:进击webpack 4 (基础篇 一) webpack.config.js基础配置 webpack 有4大概念 入口(entry) 输出(output) load...

    FleyX 评论0 收藏0
  • 浅谈webpack4.0 性能优化

    摘要:中在性能优化所做的努力,也大抵围绕着这两个大方向展开。因此,将依赖模块从业务代码中分离是性能优化重要的一环。大型库是否可以通过定制功能的方式减少体积。这又违背了性能优化的基础。接下来可以抓住一些细节做更细的优化。中,为默认启动这一优化。 前言:在现实项目中,我们可能很少需要从头开始去配置一个webpack 项目,特别是webpack4.0发布以后,零配置启动一个项目成为一种标配。正因为...

    leanxi 评论0 收藏0
  • 重学计算机组成原理(三)- 进击,更强的性能!

    摘要:在上一篇中我们谈到过程序的执行时间指令数要提升计算机的性能,可以从上面这三方面着手。在摩尔定律和并行计算之外,在整个计算机组成层面,还有这样几个原则性的性能提升方法。 showImg(https://ask.qcloudimg.com/http-save/1752328/uskvyzme4j.png); 在上一篇中,我们谈到过 程序的CPU执行时间 = 指令数×CPI×Clock Cy...

    Tecode 评论0 收藏0
  • 进击的weex 第二发 weex的各种坑

    摘要:各种错误处理错误使用模块发送请求时报错。不支持但靠后的元素层级更高支持四种伪类所有组件都支持但只有组件和组件支持。篇不支持值仅支持和如果定位元素超过容器边界,在下,超出部分将不可见,原因在于端元素默认值为,但目前暂不支持设置。 各种错误处理 1.错误:ReferenceError: global is not defined 使用stream模块发送请求时报错。 showImg(htt...

    wangbjun 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<