为了账号安全,请及时绑定邮箱和手机立即绑定

谈谈webpack2(2)- 谈谈v2版本

谈谈V2版本

主要是介绍之前在webpack1中忽略的以及v2版本中新加的一些东西。

1. caching(缓存)

浏览器为了不重复加载相同的资源,因此加入了缓存功能。通常如果请求的文件名没有变的话,浏览器就认为你请求了相同的资源,因此加载的文件就是从缓存里面拿取的,这样就会造成一个问题,实际上确实你的文件内容变了,但是文件名没有变化,这样还是从缓存中加载文件的话,就出事了。

那么,之前传统的做法就是给每个文件打上加上版本号,例如这样:

app.js?version=1
app.css?version=1

每次变动的时候就给当前的版本号加1,但是如果每次只有一个文件内容变化就要更新所有的版本号,那么没有改变的文件对于浏览器来说,缓存就失效了,需要重新加载,这样就很浪费了。那么,结合数据摘要算法,版本号根据文件内容生成,那么现在的版本可能是这样的。

// before
app.js?version=0add34
app.css?version=1ef4a2

// after
// change app.js content
app.js?versoin=2eda1c
app.css?version=1ef4a2

关于怎么部署前端代码,可以查看大公司怎样开发和部署前端代码

webpack为我们提供了更简单的方式,为每个文件生成唯一的哈希值。为了找到对应的入口文件对应的版本号,我们需要获取统计信息,例如这样的:

{
  "main.js": "main.facdf96690cca2fec8d1.js",
  "vendor.js": "vendor.f4ba2179a28531d3cec5.js"
}

同时,我们结合html-webpack-plugin使用的话,就不需要这么麻烦,他会自动给文件带上对应的版本。具体看法参看之前写的webpack1知识梳理,那么我们现在的配置变成了这个样子:

npm install webpack-manifest-plugin --save-dev

// webpack.config.js
module.exports = {
    entry : { /* ... */ },
    output : {
        path : path.resolve(__dirname, 'build-init'),
        filename : '[name].[chunkhash].js',
        chunkFilename : '[name].[chunkhash].js'
    },
    module : {
        // ...
    },
    plugins : [
        new htmlWebpackPlugin({
            title : 'webpack caching'
        }),
        new WebpackManifestPlugin()
    ]
}

html引入情况

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>webpack caching</title>
  </head>
  <body>
  <div id="container"></div>
  <script type="text/javascript" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="main.facdf96690cca2fec8d1.js"></script><script type="text/javascript" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="vendor.f4ba2179a28531d3cec5.js"></script></body>
</html>

WARNNING:

不要在开发环境下使用[chunkhash],因为这会增加编译时间。将开发和生产模式的配置分开,并在开发模式中使用[name].js的文件名,在生产模式中使用[name].[chunkhash].js文件名。

为了使文件更小化,webpack使用标识符而不是模块名称,在编译的时候会生成一个名字为manifest的chunk块,并且会被放入到entry中。那么当我们更新了部分内容的时候,由于hash值得变化,会引起manifest块文件重新生成,这样就达不到长期缓存的目的了。webpack提供了一个插件ChunkManifestWebpackPlugin,它会将manifest映射提取到一个单独的json文件中,这样在manifest块中只需要引用而不需要重新生成,所以最终的配置是这样的:

var path = require('path'),
    webpack = require('webpack'),
    htmlWebpackPlugin = require('html-webpack-plugin'),
    ChunkManifestWebpackPlugin = require('chunk-manifest-webpack-plugin'),
    WebpackChunkHash = require('webpack-chunk-hash');

module.exports = {
    entry : {
        main : path.resolve(__dirname, 'js/app.js'),
        vendor : path.resolve(__dirname, 'js/vendor.js')
    },
    output : {
        path : path.resolve(__dirname, 'build'),
        filename : '[name].[chunkhash].js',
        chunkFilename : '[name].[chunkhash].js'
    },
    module : {
        // ...
    },
    plugins : [
        new webpack.optimize.CommonsChunkPlugin({
            name : ['vendor', 'manifest'],
            minChunks : Infinity
        }),
        new webpack.HashedModuleIdsPlugin(),
        new WebpackChunkHash(),
        new htmlWebpackPlugin({
            title : 'webpack caching'
        }),
        new ChunkManifestWebpackPlugin({
            filename : 'chunk-mainfest.json',
            manifestVariable : 'webpackManifest',
            inlineManifest : true
        })
    ]
}

tips:如果还不是很明白,去对比一下加了ChunkManifestWebpackPlugin和没加的区别就可以清楚的感受到了。在本文的代码文件夹caching中可以看到这一差别

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消