webpack-webpackConfig-plugin 配置彩民之家高手论坛

2019-10-13 04:24 来源:未知

四、chunkID

事实上情况中分块的个数的逐个在再三编写翻译之间基本上都以固定的, 不太轻松爆发变化。

此间涉及的只是对比基础的模块拆分,还应该有一点点任何境况未有设想到,例如异步加载组件中带有公共模块,能够重新将公共模块举行抽离。形成异步公共 chunk 模块。有想深远学习的能够看那篇小说:Webpack 大法之 Code Splitting

webpack.optimize.CommonsChunkPlugin

  • 语法:

    new webpack.optimize.CommonsChunkPlugin({

    name: 'commons/commons',      
    filename: '[name]/bundle.js',
    minChunks: 4,
    

    }),

  • 作用:

收取出装有通用的一些,参数:

  1. name: 'commons/commons' : 给那些蕴藏公共代码的chunk命个名(独一标志)
  2. chunks: 表示供给在什么chunk(也可以领略为webpack配置中entry的每一种)里寻找国有代码实行打包。不安装此参数则暗中同意提取范围为全体的chunk
  3. filename: '[name]/bundle.js' :怎么着命名打包后生育的js文件,也是能够用上[name]、[hash]、[chunkhash]那一个变量的,  例子就是'commons/commons/bundle.js'了 (最终生成文书的门路是基于webpack配置中的ouput.path和方面CommonsChunkPlugin的filename参数来拼的)
  4. minChunks: 4, : 公共代码的决断标准:某些js模块被有个别个chunk加载了才总算集体代码

 

webpack 做缓存的片段在乎点

  1. CSS 文件 hash 值失效的标题
  2. 不建议线上宣布使用 DllPlugin 插件

ExtractTextPlugin

  • 语法:

    new ExtractTextPlugin('[name]/styles.css'),

  • 作用:

抽取出chunk的css , 

ExtractTextPlugin的初步化参数相当的少,独一的必填项是filename参数,相当于什么来定名生成的CSS文件。跟webpack配置里的output.filename参数近似,那ExtractTextPlugin的filename参数也同意接纳变量,包蕴[id]、[name]和[contenthash];理论上的话即使唯有贰个chunk,那么不用这几个变量,写死贰个文书名也是足以的,但出于大家要做的是多页应用,必然存在三个chunk(起码每一种entry都对应一个chunk啦)

在这间配置的[name]相应的是chunk的name,在webpack配置中把各种entry的name都按index/index、index/login那样的款型来安装了,那么最后css的路线就能像这么:build/index/index/styles.css,跟chunk的js文件放一块了(js文件的门径形如build/index/index/entry.js)

备注: 还要在css-loader , less-loader , postcss-loader 等关于体制的loader 配置里做相应的改动

{
  test: /.css$/,
  include: /bootstrap/,
  use: ExtractTextPlugin.extract([{
    loader: 'css-loader',
  }]),
}

 

 

 

长久化缓存

第一大家必要去解释一下,什么是悠久化缓存,在于今前后端分离的使用大行其道的背景下,前端 html,css,js 往往是以一种静态能源文件的方式存在于服务器,通过接口来获取数据来显示动态内容。那就关系到小卖部如何去安排前端代码的难题,所以就关乎到叁个立异配备的主题素材,是先布置页面,依然先布置能源?

  1. 先配备页面,再配备能源:在相互布署的日子间距内,假使有客户访谈页面,就能够在新的页面结构中加载旧的财富,何况把那些旧版本能源作为新本子缓存起来,其结果正是:客户访谈到一个体裁错乱的页面,除非手动去刷新,不然在财富缓存过期事先,页面会一贯处在混乱的场馆。
  2. 先配备能源,再布局页面:在安顿时间间隔内,有旧版本的能源本地缓存的顾客访谈网址,由于诉求的页面是旧版本,财富引用未有退换,浏览器将平昔运用本地缓存,这样属李樯常意况,但从没地方缓存恐怕缓存过期的客商在会见网站的时候,就能现出旧版本页面加载新本子财富的情景,导致页面施行错误。

进而我们须求一种配备战术来确认保障在立异大家线上的代码的时候,线上顾客也能平滑地连通並且正确展开大家的网址。

推荐介绍先看这些答复:大市肆里怎么开垦和安插前端代码?

当您读完上面包车型大巴回复,大致就能够领会,以往比较成熟的持久化缓存方案正是在静态财富的名字背后加 hash 值,因为每一次修改文件生成的 hash 值不平等,那样做的裨益在于增量式发表文件,防止覆盖掉在此之前文件进而导致线上的客户访谈失效。

因为借使成功每趟发表的静态能源(css, js, img)的名称都以举世无双的,那么作者就足以:

  • 针对 html 文件:不开启缓存,把 html 放到自身的服务器上,关闭服务器的缓存,本人的服务器只提供 html 文件和数据接口
  • 本着静态的 js,css,图片等文件:开启 cdn 和缓存,将静态能源上传到 cdn 服务商,大家得以对财富开启短期缓存,因为种种财富的门道都以天下无敌的,所以不会招致财富被遮掩,保险线上客户访谈的安定团结。
  • 老是公布更新的时候,先将静态能源(js, css, img) 传到 cdn 服务上,然后再上传 html 文件,那样既保证了老顾客能不可能健康访问,又能让新顾客观察新的页面。

地方大概介绍了下主流的前端良久化缓存方案,那么大家怎么要求做长久化缓存呢?

  1. 顾客选择浏览器第二次访谈我们的站点时,该页面引进了丰富多彩的静态财富,假若大家能成就长久化缓存的话,能够在 http 响应头加上 Cache-control 或 Expires 字段来安装缓存,浏览器能够将那一个财富一一缓存到地头。
  2. 顾客在承袭访问的时候,倘使须要重新恳请一样的静态能源,且静态能源未有过期,那么浏览器能够直接走地面缓存而不用再经过互连网央求能源。

HtmlWebpackPlugin

  • 语法:

    var glob = require('glob'); var path = require('path'); var options = { cwd: './src/pages', // 在pages目录里找 sync: true, // 这里不可能异步,只好同步 }; var globInstance = new glob.Glob('!()*/!()*', options); // 思索到多个页面共用HTML等财富的动静,跳过以'_'开首的目录 var pageArr = globInstance.found; // 二个数组,形如['index/index', 'index/login', 'alert/index'] var configPlugins = []; pageArr.forEach((page) => { const htmlPlugin = new HtmlWebpackPlugin({

    filename: `${page}/page.html`,
    template: path.resolve(dirVars.pagesDir, `./${page}/html.js`),
    // 意思是加载 page 下面的js , 和加载 commons/commons 目录下的js
    chunks: [page, 'commons/commons'],
    hash: true, // 为静态资源生成hash值
    xhtml: true,
    

    }); configPlugins.push(htmlPlugin); });

  • 作用:

生成html,参数:

  1. filename  `${page}/page.html`, : 生成的文件名字,多页面就能够有七个 HtmlWebpackPlugin ,平时使用循环生成八个数组
  2. template : path.resolve(dirVars.pagesDir, `./${page}/html.js`),   生成的html 基于的沙盘
  3. chunks : [ page, 'commons/commons'] : 意思是加载 变量page 和  commons/commons 目录下的js
  4. hash: true : 为静态财富生成hash值

 

一、源代码变化:

一清二楚不用多说,缓存必须求刷新,不然就有毛病了

ProvidePlugin

  • 语法:

    module.export = {

    plugins: [
         new webpack.ProvidePlugin({
             $: 'jquery',
             jQuery: 'jquery',
             'window.jQuery': 'jquery',
             'window.$': 'jquery',
        }),
    ]
    

    }

  • 作用:

rovidePlugin的机制是:当webpack加载到有些js模块里,出现了未定义且名称相符(字符串完全合作)配置中key的变量时,会自行require配置中value所钦命的js模块

行使ProvidePlugin还应该有个好处,便是,你和睦写的代码里,再!也!不!用!require!jQuery!啦!

延伸:

{
  test: require.resolve('jquery'), // 此loader配置项的对象是NPM中的jquery
  loader: 'expose?$!expose?jQuery', // 先把jQuery对象注明成为全局变量`jQuery`,再通过管道进一步又声称成为全局变量`$`
},

有了ProvidePlugin为嘛还必要expose-loader?

倘令你有着的jQuery插件皆以用webpack来加载的话,的确用ProvidePlugin就足够了;

唯独总有那个供给是只可以用<script>来加载的

 

不提出线上宣布使用 DllPlugin 插件

为啥那样说吗?因为近年来有朋友来问作者,他们 leader 不让在线上用 DllPlugin 插件,来问小编何以?

DllPlugin 本人有多少个毛病:

  1. 先是你须求额外多配备一份 webpack 配置,扩充专业量。
  2. 里面一个页面用到了八个体量非常的大的第三方正视库而别的页面根本无需运用,但若平素将它包裹在 dll.js 里十分不值得,每便页面张开都要去加载这段无用的代码,不能够利用到 webpack2 的 Code Splitting 功用。
  3. 第贰遍张开的时候供给下载 dll 文件,因为您把过多库全体打在共同了,导致 dll 文件极大,第一回跻身页面加载速度极慢。

尽管你可以打包成 dll 文件,然后让浏览器去读取缓存,这样后一次就绝不再去央浼,举例你用 lodash 此中三个函数,而你用dll会将全部 lodash 文件打进去,这就能促成你加载无用代码过多,不便于首屏渲染时间。

自家认为的不错的架子是:

  1. 像 React、Vue 那样全部性偏强的库,能够生成 vendor 第三方库来去做缓存,因为你相似技术系统是原则性的,一个站点里面基本上都会用到统一手艺系统,所以生成 vendor 库用于缓存。
  2. 像 antd、lodash 这种成效性组件库,能够由此 tree shaking 来张开清除,只保留有用的代码,千万不要一贯打到 vendor 第三方Curry,否则你将多量举办无用的代码。

三、webpack 生成的模块 moduleid

在 webpack2 中默许加载 OccurrenceOrderPlugin 这一个插件,OccurrenceOrderPlugin 插件会按引进次数最多的模块实行排序,引进次数的模块的 moduleId 越小,可是那照旧是不平稳的,随着你代码量的扩张,即便代码引用次数的模块 moduleId 越小,越不易于生成,可是免不了还是不明确的。

私下认可意况下,模块的 id 是其一模块在模块数组中的索引。OccurenceOrderPlugin 会将援用次数多的模块放在前边,在历次编写翻译时模块的相继未有分歧的,假诺你改改代码时新增添或删除了一部分模块,那将恐怕会潜移暗化到具有模块的 id。

一级试行方案是因而 HashedModuleIdsPlugin 这么些插件,这么些插件会根据模块的相对路线生成多个长度独有四个人的字符串作为模块的 id,既掩饰了模块的渠道消息,又降低了模块 id 的长度。

那样一来,更换 moduleId 的法门就唯有文件路线的改变了,只要您的文书路线值不改变,生成四个人的字符串就不改变,hash 值也不改变。扩张或删除业务代码模块不会对 moduleid 发生任何影响。

module.exports = { plugins: [ new webpack.HashedModuleIdsPlugin(), // 放在最前方 // ... ] }

1
2
3
4
5
6
7
module.exports = {
  plugins: [
    new webpack.HashedModuleIdsPlugin(),
    // 放在最前面
    // ...
  ]
}

前言

前不久在看 webpack 如何是好长久化缓存的剧情,发现中间依然有部分坑点的,正好一时间就将它们整理计算一下,读完本文你大概能够知情:

  1. 怎样是长久化缓存,为何做悠久化缓存?
  2. webpack 怎么办悠久化缓存?
  3. webpack 做缓存的有个别注意点。

webpack 如何是好悠久化缓存

上面简要介绍完漫长化缓存,上面那个才是非同常常,那么大家应当怎么在 webpack 中开展持久化缓存的呢,大家必要产生以下两点:

  1. 有限支撑 hash 值的独一性,即为每种打包后的财富转移二个并世无两的 hash 值,只要打包内容不均等,那么 hash 值就不均等。
  2. 保障 hash 值的安静,大家需求达成修改有些模块的时候,唯有受影响的打包后文件 hash 值改变,与该模块非亲非故的打包文件 hash 值不改变。

hash 文件名是促成悠久化缓存的首先步,最近 webpack 有两种总结 hash 的艺术([hash] 和 [chunkhash])

  • hash 代表每便 webpack 在编写翻译的长河中会生成独一的 hash 值,在类型中别的二个文件更换后就能被再次创造,然后 webpack 总括新的 hash 值。
  • chunkhash 是基于模块计算出来的 hash 值,所以有个别文件的改观只会影响它本身的 hash 值,不会耳熏目染此外文件。

由此只要你只是只有地将享有内容打包成同一个文书,那么 hash 就可以预知满意你了,借让你的项目事关到拆包,分模块实行加载等等,那么您供给用 chunkhash,来保管每趟换代之后唯有连带的文书 hash 值发生改变。

由此我们在一份具备长久化缓存的 webpack 配置相应长这么:

module.exports = { entry: __dirname '/src/index.js', output: { path: __dirname '/dist', filename: '[name].[chunkhash:8].js', } }

1
2
3
4
5
6
7
module.exports = {
  entry: __dirname '/src/index.js',
  output: {
    path: __dirname '/dist',
    filename: '[name].[chunkhash:8].js',
  }
}

上边代码的含义就是:以 index.js 为进口,将有所的代码全体打包成一个文书取名叫 index.xxxx.js 并置于 dist 目录下,今后大家得以在历次换代项目标时候做到生成新命名的文本了。

假假如应付不难的场所,那样做就够了,可是在巨型多页面使用中,我们一再需求对页面实行质量优化:

  1. 暌违业务代码和第三方的代码:之所以将工作代码和第三方代码分离出来,是因为事情代码更新频率高,而第三方代码更新迭代速度慢,所以我们将第三方代码(库,框架)举行抽离,那样能够丰盛利用浏览器的缓存来加载第三方库。
  2. 按需加载:举例在选择 React-Router 的时候,当客商须求拜见到某些路由的时候再去加载对应的零件,那么客商没有供给在一开首的时候就将全数的路由组件下载到本地。
  3. 在多页面使用中,咱们每每能够将集人体模型块实行抽离,比方 header, footer 等等,这样页面在开展跳转的时候那个公共模块因为存在于缓存里,就足以平素开展加载了,并不是再进行互联网哀告了。

那么怎样举办拆包,分模块进行加载,那就须要 webpack 内置插件:CommonsChunkPlugin,下边小编将因而贰个例证,来解说 webpack 该怎么举办安排。

正文的代码放在自身的 Github 上,风野趣的可以下载来看看:

git clone cd blog/code/multiple-page-webpack-demo npm install

1
2
3
git clone https://github.com/happylindz/blog.git
cd blog/code/multiple-page-webpack-demo
npm install

翻阅下面包车型大巴剧情前边作者强烈提出你看下小编事先的稿子:深刻驾驭 webpack 文件打包机制,驾驭 webpack 文件的打包的编写制定推进你越来越好地促成长久化缓存。

事例大约是这么陈说的:它由三个页面组成 pageA 和 pageB

// src/pageA.js import componentA from './common/componentA'; // 使用到 jquery 第三方库,需要抽离,制止业务打包文件过大 import $ from 'jquery'; // 加载 css 文件,一部分为公共样式,一部分为唯有体制,供给抽离 import './css/common.css' import './css/pageA.css'; console.log(componentA); console.log($.trim(' do something ')); // src/pageB.js // 页面 A 和 B 都用到了国有模块 componentA,须要抽离,幸免双重加载 import componentA from './common/componentA'; import componentB from './common/componentB'; import './css/common.css' import './css/pageB.css'; console.log(componentA); console.log(componentB); // 用到异步加载模块 asyncComponent,要求抽离,加载首屏速度 document.getElementById('xxxxx').add伊夫ntListener('click', () => { import( /* webpackChunkName: "async" */ './common/asyncComponent.js').then((async) => { async(); }) }) // 公共模块基本长那样 export default "component X";

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// src/pageA.js
import componentA from './common/componentA';
 
// 使用到 jquery 第三方库,需要抽离,避免业务打包文件过大
import $ from 'jquery';
 
// 加载 css 文件,一部分为公共样式,一部分为独有样式,需要抽离
import './css/common.css'
import './css/pageA.css';
 
console.log(componentA);
console.log($.trim('    do something   '));
 
// src/pageB.js
// 页面 A 和 B 都用到了公共模块 componentA,需要抽离,避免重复加载
import componentA from './common/componentA';
import componentB from './common/componentB';
import './css/common.css'
import './css/pageB.css';
 
console.log(componentA);
console.log(componentB);
 
// 用到异步加载模块 asyncComponent,需要抽离,加载首屏速度
document.getElementById('xxxxx').addEventListener('click', () => {
  import( /* webpackChunkName: "async" */
    './common/asyncComponent.js').then((async) => {
      async();
  })
})
 
// 公共模块基本长这样
export default "component X";

上面包车型地铁页面内容主导归纳关联到了我们拆分模块的三种形式:拆分公共库,按需加载和拆分公共模块。那么接下去要来配置 webpack:

const path = require('path'); const webpack = require('webpack'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: { pageA: [path.resolve(__dirname, './src/pageA.js')], pageB: path.resolve(__dirname, './src/pageB.js'), }, output: { path: path.resolve(__dirname, './dist'), filename: 'js/[name].[chunkhash:8].js', chunkFilename: 'js/[name].[chunkhash:8].js' }, module: { rules: [ { // 用正则去相配要用该 loader 调换的 CSS 文件 test: /.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ["css-loader"] }) } ] }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'common', minChunks: 2, }), new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: ({ resource }) => ( resource && resource.indexOf('node_modules') >= 0 && resource.match(/.js$/) ) }), new ExtractTextPlugin({ filename: `css/[name].[chunkhash:8].css`, }), ] }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
  entry: {
    pageA: [path.resolve(__dirname, './src/pageA.js')],
    pageB: path.resolve(__dirname, './src/pageB.js'),
  },
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'js/[name].[chunkhash:8].js',
    chunkFilename: 'js/[name].[chunkhash:8].js'
  },
  module: {
    rules: [
      {
        // 用正则去匹配要用该 loader 转换的 CSS 文件
        test: /.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: ["css-loader"]
        })  
      }
    ]
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'common',
      minChunks: 2,
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: ({ resource }) => (
        resource && resource.indexOf('node_modules') >= 0 && resource.match(/.js$/)
      )
    }),
    new ExtractTextPlugin({
      filename: `css/[name].[chunkhash:8].css`,
    }),
  ]
}

先是个 CommonsChunkPlugin 用于抽离公共模块,相当于是说 webpack 大佬,借令你见到有个别模块被加载三回即以上,那么请您帮作者移到 common chunk 里面,这里 minChunks 为 2,粒度拆解最细,你能够依靠本人的实际上景况,看采纳是用多少次模块才将它们抽离。

第二个 CommonsChunkPlugin 用来提取第三方代码,将它们实行抽离,判定能源是或不是来自 node_modules,假如是,则印证是第三方模块,那就将它们抽离。也正是是告诉 webpack 大佬,借使您看到有个别模块是来自 node_modules 目录的,而且名字是 .js 结尾的话,麻烦把她们都移到 vendor chunk 里去,假设 vendor chunk 不设有的话,就创办二个新的。

如此布署有哪些平价,随着职业的加强,大家依赖的第三方库代码很或然会更为多,如若大家特意布署三个入口来寄存在第三方代码,这时候我们的 webpack.config.js 就能够成为:

// 不方便人民群众开展 module.exports = { entry: { app: './src/main.js', vendor: [ 'vue', 'axio', 'vue-router', 'vuex', // more ], }, }

1
2
3
4
5
6
7
8
9
10
11
12
13
// 不利于拓展
module.exports = {
  entry: {
    app: './src/main.js',
    vendor: [
      'vue',
      'axio',
      'vue-router',
      'vuex',
      // more
    ],
  },
}

其多少个 ExtractTextPlugin 插件用于将 css 从打包好的 js 文件中抽离,生成独立的 css 文件,想象一下,当您只是修改了下样式,并未有改变页面包车型客车魔法逻辑,你早晚不希望您的 js 文件 hash 值变化,你势必是希望 css 和 js 能够互为分开,且互不影响。

运维 webpack 后得以看见打包之后的功效:

├── css │   ├── common.2beb7387.css │   ├── pageA.d178426d.css │   └── pageB.33931188.css └── js ├── async.03f28faf.js ├── common.2beb7387.js ├── pageA.d178426d.js ├── pageB.33931188.js └── vendor.22a1d956.js

1
2
3
4
5
6
7
8
9
10
11
├── css
│   ├── common.2beb7387.css
│   ├── pageA.d178426d.css
│   └── pageB.33931188.css
└── js
    ├── async.03f28faf.js
    ├── common.2beb7387.js
    ├── pageA.d178426d.js
    ├── pageB.33931188.js
    └── vendor.22a1d956.js
 

能够看看 css 和 js 已经分离,何况大家对模块进行了拆分,保证了模块 chunk 的独一性,当您每一遍换代代码的时候,会变卦不等同的 hash 值。

独一性有了,那么大家必要确认保证 hash 值的稳定,试想下如此的光景,你一定不希望您改改某有些的代码(模块,css)导致了文件的 hash 值全变了,那么明确是不明智的,那么我们去做到 hash 值变化最小化呢?

换句话说,大家将要寻觅 webpack 编写翻译中会导致缓存失效的元素,想艺术去消除或优化它?

影响 chunkhash 值变化根本由以下多个部分引起的:

  1. 带有模块的源代码
  2. webpack 用于运维运作的 runtime 代码
  3. webpack 生成的模块 moduleid(包蕴富含模块 id 和被援引的凭借模块 id)
  4. chunkID

那四局地只要有自由部分发生变化,生成的分块文件就分歧了,缓存也就能够失效,上面就从四个部分每种介绍:

二、webpack 运行运转的 runtime 代码:

看过自家事先的篇章:浓郁领悟 webpack 文件打包机制 就能够分晓,在 webpack 运营的时候需求试行一些起动代码。

(function(modules) { window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) { // ... }; function __webpack_require__(moduleId) { // ... } __webpack_require__.e = function requireEnsure(chunkId, callback) { // ... script.src = __webpack_require__webpack-webpackConfig-plugin 配置彩民之家高手论坛。.p "" chunkId "." ({"0":"pageA","1":"pageB","3":"vendor"}[chunkId]||chunkId) "." {"0":"e72ce7d4","1":"69f6bbe3","2":"9adbbaa0","3":"53fa02a7"}[chunkId]

  • ".js"; }; })([]);
1
2
3
4
5
6
7
8
9
10
11
12
(function(modules) {
  window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) {
    // ...
  };
  function __webpack_require__(moduleId) {
    // ...
  }
  __webpack_require__.e = function requireEnsure(chunkId, callback) {
    // ...
    script.src = __webpack_require__.p "" chunkId "." ({"0":"pageA","1":"pageB","3":"vendor"}[chunkId]||chunkId) "." {"0":"e72ce7d4","1":"69f6bbe3","2":"9adbbaa0","3":"53fa02a7"}[chunkId] ".js";
  };
})([]);

差十分的少内容像上面那样,它们是 webpack 的片段起步代码,它们是局地函数,告诉浏览器怎么着加载 webpack 定义的模块。

个中有一行代码每一趟换代都会更动的,因为运维代码须求知道地掌握 chunkid 和 chunkhash 值得对应涉及,那样在异步加载的时候能力科学地拼接出异步 js 文件的路子。

那么这有个别代码最终放在哪个文件呢?因为我们刚刚配置的时候最终生成的 common chunk 模块,那么这一部分运维时代码会被一贯内置在里面,那就招致了,大家每趟换代我们业务代码(pageA, pageB, 模块)的时候, common chunkhash 会一向变化,可是那明显不相符大家的考虑,因为我们只是要用 common chunk 用来存放公共模块(这里指的是 componentA),那么笔者 componentA 都没去修改,凭啥 chunkhash 需求变了。

故此大家要求将那有的 runtime 代码抽离成单身文件。

module.exports = { // ... plugins: [webpack-webpackConfig-plugin 配置彩民之家高手论坛。 // ... // 放到任何的 CommonsChunkPlugin 前边 new webpack.optimize.CommonsChunkPlugin({ name: 'runtime', minChunks: Infinity, }), ] }

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
  // ...
  plugins: [
    // ...
    // 放到其他的 CommonsChunkPlugin 后面
    new webpack.optimize.CommonsChunkPlugin({
      name: 'runtime',
      minChunks: Infinity,
    }),
  ]
}

这一定于是告诉 webpack 帮本身把运维时代码抽离,放到单独的公文中。

├── css │   ├── common.4cc08e4d.css │   ├── pageA.d178426d.css │   └── pageB.33931188.css └── js ├── async.03f28faf.js ├── common.4cc08e4d.js ├── pageA.d178426d.js ├── pageB.33931188.js ├── runtime.8c79fdcd.js └── vendor.cef44292.js

1
2
3
4
5
6
7
8
9
10
11
12
├── css
│   ├── common.4cc08e4d.css
│   ├── pageA.d178426d.css
│   └── pageB.33931188.css
└── js
    ├── async.03f28faf.js
    ├── common.4cc08e4d.js
    ├── pageA.d178426d.js
    ├── pageB.33931188.js
    ├── runtime.8c79fdcd.js
    └── vendor.cef44292.js
 

多生成了叁个 runtime.xxxx.js,未来你在更换业务代码的时候,common chunk 的 hash 值就不会变了,取而代之的是 runtime chunk hash 值会变,既然那有的代码是动态的,能够透过 chunk-manifest-webpack-plugin 将她们 inline 到 html 中,减弱壹次互联网须求。

参照链接:

  • Webpack中hash与chunkhash的分裂,甚至js与css的hash指纹解耦方案
  • webpack多页应用架构种类(十六):善用浏览器缓存,该去则去,该留则留
  • 用 webpack 落成悠久化缓存
  • Webpack 真正的有头有尾缓存完毕

    2 赞 2 收藏 评论

彩民之家高手论坛 1

CSS 文件 hash 值失效的主题素材:

ExtractTextPlugin 有个比较严重的难题,那正是它生成文书名所用的[chunkhash]是直接取自于援引该 css 代码段的 js chunk ;换句话说,若是小编只是修改 css 代码段,而不动 js 代码,那么最后生成出来的 css 文件名依然未有成形。

于是大家需求将 ExtractTextPlugin 中的 chunkhash 改为 contenthash,顾名思义,contenthash 代表的是文本文件内容的 hash 值,也便是唯有 style 文件的 hash 值。那样编写翻译出来的 js 和 css 文件就有独立的 hash 值了。

module.exports = { plugins: [ // ... new ExtractTextPlugin({ filename: `css/[name].[contenthash:8].css`, }), ] }

1
2
3
4
5
6
7
8
module.exports = {
  plugins: [
    // ...
    new ExtractTextPlugin({
      filename: `css/[name].[contenthash:8].css`,
    }),
  ]
}

假如你利用的是 webpack2,webpack3,那么恭喜您,那样就足足了,js 文件和 css 文件修改都不会影响到互相的 hash 值。那要是您利用的是 webpack1,那么就能够油可是生难题。

具体来说便是 webpack1 和 webpack 在测算 chunkhash 值得分化:

webpack1 在事关的时候并不曾思量像 ExtractTextPlugin 会将模块内容抽离的难点,所以它在总计 chunkhash 的时候是通过包装在此之前模块内容去总结的,约等于说在图谋的时候 css 内容也蕴涵在内,之后才将 css 内容抽离成单身的公文,

那就是说就会冒出:假使只修改了 css 文件,未修改援引的 js 文件,那么编写翻译输出的 js 文件的 hash 值也会退换。

对此,webpack2 做了修正,它是基于打包后文件内容来总计 hash 值的,所以是在 ExtractTextPlugin 抽离 css 代码之后,所以就海市蜃楼上述如此的标题。如若不幸的您还在应用 webpack1,那么推荐你使用 md5-hash-webpack-plugin 插件来改动 webpack 计算hash 的计划。

结语

好了,感觉自身又扯了重重,近日在看 webpack 确实获得累累,希望我们能从小说中也能享有收获。别的推荐再度推荐一下自家前边写的篇章,能够越来越好地帮你领悟文件缓存机制:深切领会webpack 文件打包机制

webpack 长久化缓存施行

2018/01/15 · JavaScript · webpack, 缓存

初藳出处: happylindz   

TAG标签: JavaScript webpack
版权声明:本文由彩民之家高手论坛发布于前端知识,转载请注明出处:webpack-webpackConfig-plugin 配置彩民之家高手论坛