Dieser Artikel stellt hauptsächlich die erweiterte Verwendung von Webpack vor – Caching und unabhängige Verpackung. Der Herausgeber findet ihn recht gut, daher werde ich ihn jetzt mit Ihnen teilen und als Referenz verwenden. Lassen Sie uns dem Herausgeber folgen und einen Blick darauf werfen.
Dieser Artikel stellt die Verwendung von Caching und unabhängiger Verpackung vor. Ich hoffe, er wird für alle hilfreich sein
Werfen wir zunächst einen Blick auf die Grundlagen der Webpack-Konfiguration:var path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') } }
import _ from 'lodash'; function component() { var element = document.createElement('p'); element.innerHTML = _.join(['Hello', 'webpack'], ' '); return element; } document.body.appendChild(component());
Zuerst müssen wir die gepackten Dateien trennen. Zweitens lösen Sie das Caching-Problem.
const path = require('path'); const webpack = require('webpack'); module.exports = { entry: { common: ['lodash'], app: './src/index.js' }, output: { filename: '[name].[hash].js', path: path.resolve(__dirname, 'dist') }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'common' // 指代index.js引入的lodash库 }) ] }
Code kopieren Der Code lautet wie folgt:
new CleanWebpackPlugin(['dist']) // Für jedes zum Plugin-Array hinzufügen Vor dem Verpacken sollten alle zuvor verpackten Dateien im Verpackungsordner gelöscht werden.
Wir konfigurieren wie folgt: Ändern Sie [name].[hash].js in der Ausgabe in [name].[chunkhash].js, sodass jede Datei einen eindeutigen Hash-Wert generiert:
const path = require('path'); const webpack = require('webpack'); module.exports = { entry: { common: ['lodash'], app: './src/index.js' }, output: { filename: '[name].[chunkhash].js', path: path.resolve(__dirname, 'dist') }, plugins: [ new CleanWebpackPlugin(['dist']), new webpack.optimize.CommonsChunkPlugin({ name: 'common' // 指代index.js引入的lodash库 }) ] }
原因是:为了最小化生成的文件大小,webpack使用标识符而不是模块名称,在编译期间生成标识符,并映射到块文件名,然后放入一个名为chunk manifest的JS对象中。重点就在于!!当我们使用CommonsChunkPlugin分离代码时,被分离出来的代码(本文中的lodash库,被打包为common。),会默认被移动到entry中最后一个入口进行打包(第一个入口是index.js)。重要的是,chunk manifest将随着这些被分离出来的代码共同打包!!!
由于我们更改源代码后,不但会更新app的hash值,还会生成新的映射,然后新的映射又会和资源代码一同打包,又由于chunkhash是根据内容生成hash的,那么加入了新的映射对象chunk manifest的资源代码被打包后,hash自然也会发生改变。这反过来,产生的新hash将使长效缓存失效。
那么接下来我们需要做的就是讲 manifest分离出来。这里我们利用一个CommonsChunkPlugin一个较少有人知道的功能,能够在每次修改后的构建中将manifest提取出来,通过指定entry中未用到的名称,此插件会自动将我们需要的内容提取到单独的包中。
故再额外配置一个CommonsChunkPlugin:
const path = require('path'); const webpack = require('webpack'); module.exports = { entry: { common: ['lodash'], app: './src/index.js' }, output: { filename: '[name].[chunkhash].js', path: path.resolve(__dirname, 'dist') }, plugins: [ new CleanWebpackPlugin(['dist']), new webpack.optimize.CommonsChunkPlugin({ name: 'common' // 指代index.js引入的lodash库 }), new webpack.optimize.CommonsChunkPlugin({ name: 'manifest' // 用于提取manifest }) ] }
webpack打包后:
从这里可以证明之前所说的manifest被打包进了common!!!仔细看之前的图:common的Size都是547kb,到这里common大小是541kb 而manifest大小正好为5.85kb,加起来正好为547kb。
然后我们修改index.js再次打包:
从这里可以发现!!我们修改了源代码,common的hash值已经不再发生改变了!到这里可以达到我们不缓存源代码缓存资源文件的目的了。
但是可别高兴得太早!!我们做了一个很小的修改,交换了entry中 app 和 common的顺序(对比上一个代码段):
const path = require('path'); const webpack = require('webpack'); module.exports = { entry: { app: './src/index.js', common: ['lodash'] }, output: { filename: '[name].[chunkhash].js', path: path.resolve(__dirname, 'dist') }, plugins: [ new CleanWebpackPlugin(['dist']), new webpack.optimize.CommonsChunkPlugin({ name: 'common' // 指代index.js引入的lodash库 }), new webpack.optimize.CommonsChunkPlugin({ name: 'manifest' // 用于提取manifest }) ] }
打包后:
这里发现对比上一张图片发现,common的hash值又发生改变了!!而且根本没有更改index.js的内容app的hash也变了,只是换了一下顺序而已!
大家注意看本张图与上一张图的模块解析顺序([1],[2],[3]...之后所对应的模块)。发现上一张图,lodash第一个解析,而现在lodash最后一个解析。
这就是hash更变的原因:这是因为每个module.id 会基于默认的解析顺序(resolve order)进行增量。也就是说,当解析顺序发生变化,ID 也会随之改变,所以hash值也会发生变化。
有人可能会决定,一般我们都不会更换webpack.config.js中entry的入口顺序,那么是否我就不会遇见这个问题了。答案是否定的,除否你能保证资源文件都写在entry的顶部。否则会出现这样的情况:
假如entry的顺序为: app -> common, 那么解析顺序为 index.js → lodash。 如果之后index.js引入了 print.js,那么解析顺序变为 index.js → print.js -> lodash。
以上,我们并没有在entry中更改入口顺序,解析的顺序还是会发生改变,common的hash还是会发生,不能缓存。
这里我们就引入一个新的组件:HashedModuleIdsPlugin:根据hash生成ID(NamedModulesPlugin也具有同样的效果,但是是根据路径名生成ID,可读性更高,也由此编译时间会相对长一些)。 这样module.id就不会使用数字标识符,而使用hash:
const path = require('path'); const webpack = require('webpack'); module.exports = { entry: { common: ['lodash'], app: './src/index.js' }, output: { filename: '[name].[chunkhash].js', path: path.resolve(__dirname, 'dist') }, plugins: [ new CleanWebpackPlugin(['dist']), new webpack.HashedModuleIdsPlugin(), // 引入该插件 new webpack.optimize.CommonsChunkPlugin({ name: 'common' // 指代index.js引入的lodash库 }), new webpack.optimize.CommonsChunkPlugin({ name: 'manifest' // 用于提取manifest }) ] }
打包发现,之前[ ]里都是数字,现在都是一些字符,
接下来,我们再把app和common的顺序调换一下,并且随意修改index.js,再次打包:
现在大功告成,common的hash没有改变,而因为更变了内容app的hash改变了,这正是我们想要的结果。
Das obige ist der detaillierte Inhalt vonÜber die Verwendung von Webpack-Caching und unabhängiger Verpackung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!