• webpack打包分离第三方库和业务代码


    使用webpack打包工程,通常会需要分离第三方类库和应用本身的代码,因为第三方类库更新频率不高,这样浏览器可以直接从缓存读,不需要项目每次上线再获取一次。

    以react为例,正常情况下,最初是这么配置的:

    复制代码
     1 module.exports = {
     2     entry: {
     3         app: "./src/App.js",
     4         vendor: ["react", "react-dom"]
     5     },
     6     output: {
     7         path: __dirname + "/dist",
     8         filename: "[name].[chunkhash:8].js",
     9         publicPath: "/dist/"
    10     },
    11     ...
    12     plugins: [
    13         ...
    14         new webpack.optimize.CommonsChunkPlugin({
    15             names: ["vendor"]
    16         })
    17     ]
    18 };
    复制代码

    然后我们会发现,一旦应用代码发生变化,重新打包后app.js和vendor.js的hash值都会发生变化,具体原因大致就是由于app.js变了,webpack会生成一段runtime注入vendor.js,导致vendor.js也变了(因为两者有关联)。

    解决方法目前我知道二种比较好。

    第一种是利用webpack.DllPlugin,具体使用方法网上很多,配置稍微有点复杂,这里不列举了。

    第二种方法是利用CommonsChunkPlugin生成一个专门跟踪vendor.js变化的js文件,一般可以取名manifest.js,具体配置如下:

    复制代码
     1 module.exports = {
     2     entry: {
     3         app: "./src/App.js",
     4         vendor: ["react", "react-dom"]
     5     },
     6     output: {
     7         path: __dirname + "/dist",
     8         filename: "[name].[chunkhash:8].js",
     9         publicPath: "/dist/"
    10     },
    11     ...
    12     plugins: [
    13         ...
    14         new webpack.optimize.CommonsChunkPlugin({
    15             names: ["vendor", "manifest"]
    16         })
    17     ]
    18 };
    复制代码

    其中CommonsChunkPlugin的配置还能这么配:

    复制代码
     1 module.exports = {
     2     ...
     3     plugins: [
     4         ...
     5         new webpack.optimize.CommonsChunkPlugin({
     6             names: ["vendor"]
     7         }),
     8         new webpack.optimize.CommonsChunkPlugin({
     9             names: ["manifest"],
    10             chunks: ["vendor"]
    11         })
    12     ]
    13 };
    复制代码

    完成后我们修改应用代码,再重新打包,结果vendor.js的hash值不再发生变化。

    我看过的网上的教程,基本上都到这里就结束了。然而当我运行代码,想查看效果,结果却是空白页,chrome下有报错:

    ???

    当时真是一下就懵了。google、stackoverflow搜了好久都没找到满意的答案(可能是搜商比较低)。

    后来我无意中去看生成的index.html,发现里面插入的js顺序是这样的:

    然后再打开chrome里的第一行报错:

    发现报错是从app.js开始的。正常情况下应该是app.js引用vendor.js中的方法,即app.js的加载顺序应该在vendor.js之后,但现在顺序却颠倒了,会不会是这个原因造成的?

    于是我们手动修改index.html,交换一下app.js和vendor.js的加载顺序。再重新运行代码,结果显示正确了。

    看来是chunks注入顺序混乱导致的,那有没有方法按照正确的引用顺序注入呢?这就要看html-webpack-plugin插件了。

    原本关于html-webpack-plugin插件我们是这么配的:

    复制代码
     1 module.exports = {
     2     ...
     3     plugins: [
     4         ...
     5         new HtmlPlugin({
     6             filename: "../index.html",
     7             template: __dirname + "/src/templates/index.html"
     8         })
     9     ]
    10 };
    复制代码

    而html-webpack-plugin中有个配置项叫chunksSortMode,它可以指定chunks注入的顺序,其可以配置为:"none" | "auto" | "dependency" | {function}。默认配置是"auto"。

    现在我们加上这个配置项,并配置为"dependency":

    复制代码
     1 module.exports = {
     2     ...
     3     plugins: [
     4         ...
     5         new HtmlPlugin({
     6             filename: "../index.html",
     7             template: __dirname + "/src/templates/index.html",
     8             chunksSortMode: "dependency"
     9         })
    10     ]
    11 };
    复制代码

    然后再重新打包,再看index.html,发现这下app.js在vendor.js后面了,最后运行程序也能正常显示了。

    热爱前端技术
  • 相关阅读:
    File 类
    RocketMQ4.X 集群
    Java 的基本网络支持
    SpringBoot2.X 整合 RocketMQ4.X
    RocketMQ系列:rocketmq运维控制台使用详解(全网独家)
    RocketMQ系列:docker搭建rocketmq单机环境
    RocketMQ系列:rocketmq运维控制台搭建
    RocketMQ系列:单机快速搭建单broker环境
    Jenkins:Git拉取代码版本不对
    pip3:no acceptable C compiler found in $PATH
  • 原文地址:https://www.cnblogs.com/lcosima/p/8909986.html
Copyright © 2020-2023  润新知