webpack之代码分离-libraries

浏览器缓存机制

浏览器的缓存机制,简单的说就是将一次请求的资源保存在本地。客户端和服务端通过http请求约定怎么去使用、更新这个资源。利用这个机制,我们可以减少资源传输,提高页面加载速度。

  • Expires 规定了缓存过期时间
  • Cache-Control 规定了缓存存活时间
  • Last-Modified 该资源最后修改时间
  • If-Modified-Since 如果资源在该日期之后发生修改,则进行更新。
  • ETag ETag 是代表该文件的唯一字符串,是第二种检查缓存是否需要更新的机制。
  • If-None-Match 如果ETag与之不相同则进行更新。

代码分离

单入口只会生成一个打包的bundle.js,它既包括了页面独立的JS文件,也包含了许多从CDN获取的,公用的模块。
哪怕我们对页面的独立JS进行微小改动,bundle.js也需要重新打包。用户再次访问时,就需要下载完整的bundle.js。为了充分使用浏览器的缓存机制,我们需要将公共库单独打包。

CommonsChunkPlugin

单纯的使用多入口,因为所有依赖都要被打包,并不能解决问题。于是需要使用插件CommonsChunkPlugin

修改配置文件webpack.config.js

var webpack = require('webpack');
var path = require('path');

module.exports = function(env) {
    return {
        entry: {
            main: './index.js',
            vendor: 'moment'//引入的库
        },
        output: {
            filename: '[name].[chunkhash].js',
            path: path.resolve(__dirname, 'dist')
        },
        plugins: [
            new webpack.optimize.CommonsChunkPlugin({
                name: 'vendor' // 指定公共 bundle 的名字。
            })
        ]
    }
}

隐式生成vendor

var webpack = require('webpack');
var path = require('path');

module.exports = function() {
    return {
        entry: {
            main: './index.js'
        },
        output: {
            filename: '[name].[chunkhash].js',
            path: path.resolve(__dirname, 'dist')
        },
        plugins: [
            new webpack.optimize.CommonsChunkPlugin({
                name: 'vendor',
                minChunks: function (module) {
                   // 该配置假定你引入的 vendor 存在于 node_modules 目录中
                   return module.context && module.context.indexOf('node_modules') !== -1;
                }
            })
        ]
    };
}

Manifest

Manifest就是webapck runtime code,它支撑页面运行时,webpack可以处理打包后的文件。
当webpack只生成一个bundle时,Manifest这部分代码也被打包进入bundle。而当生成多个bundle时,这部分代码会被放入公共库vendor中。
这就导致vendor文件的hash发生改变。使得浏览器缓存无法生效。

故而,我们需要将Manifest单独独立出来。代码如下
webpack.config.js

var webpack = require('webpack');
var path = require('path');

module.exports = function(env) {
    return {
        entry: {
            main: './index.js',
            vendor: 'moment'
        },
        output: {
            filename: '[name].[chunkhash].js',
            path: path.resolve(__dirname, 'dist')
        },
        plugins: [
            new webpack.optimize.CommonsChunkPlugin({
                names: ['vendor', 'manifest'] // 指定公共 bundle 的名字。
            })
        ]
    }
};

隐式

var webpack = require('webpack');
var path = require('path');

module.exports = function() {
    return {
        entry: {
            main: './index.js' //注意这里只有一个入口
        },
        output: {
            filename: '[name].[chunkhash].js',
            path: path.resolve(__dirname, 'dist')
        },
        plugins: [
            new webpack.optimize.CommonsChunkPlugin({
                name: 'vendor',
                minChunks: function (module) {
                   // 该配置假定你引入的 vendor 存在于 node_modules 目录中
                   return module.context && module.context.indexOf('node_modules') !== -1;
                }
            }),
            //CommonChunksPlugin 将从 vendor和bundles中提取所有的公用库
            //但由于已经没有其他公用模块了,故而只会将runtime code存入manifest中
            new webpack.optimize.CommonsChunkPlugin({
                name: 'manifest' 
            })
        ]
    };
}

你可能感兴趣的:(webpack之代码分离-libraries)