Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack中的hash问题 #2

Open
SunShinewyf opened this issue Apr 25, 2017 · 1 comment
Open

webpack中的hash问题 #2

SunShinewyf opened this issue Apr 25, 2017 · 1 comment

Comments

@SunShinewyf
Copy link
Owner

SunShinewyf commented Apr 25, 2017

webpack-demo

webpack中的hash问题

简单的项目目录如下图所示:

template

webpack中的配置文件如下的时候:

  module.exports = {
      entry: {
          'example1': './example1',
          'example2': './example2'
      },
      output: {
          filename: '[name]-[hash:8].js'
      }
  };

第一次执行webpack命令的时候,会出现下面的目录:

template2

但是当改变example1.js和example2.js中的任何一个文件的时候,然后再执行webpack,就会看到下面的目录:

template3

可以看到目录中又新添了两个文件,并且两个文件名的hash值是一样的。这里又一个弊端,就是没有改变的那个文件,也会生成一个新的hash值的文件名。这是因为hash字段是根据每次编译
compilation的内容计算得到,也就是整个文件的hash值,这样的编译方式明显不太好,没有改变的文件也会随着其他文件的改变而改变
解决上面的问题有如下几种方式:

使用chunkhash

配置文件如下所示:

module.exports = {
    entry: {
        'example1': './example1',
        'example2': './example2'
    },
    output: {
        filename: '[name]-[chunkhash:8].js'
    }
};

执行webpack之后,文件目录如下所示:

template4

改变example1.js之后,然后再执行webpack,目录结构如下所示:

template5

这样就解决了上面的问题。但是当加入css文件之后,文件目录如下:

template5

并且在a.js中引入a.css,如下所示:

require('./a.css')

webpack的配置文件如下所示:

module.exports = {
    entry: {
        'a': './a',
        'b': './b'
    },
    output: {
        filename: '[name]-[chunkhash:8].js'
    },
    module: {
        loaders:[
            {
                test: /\.css$/, // Only .css files
                use: ["style-loader", "css-loader"] // Run both loaders
            }
        ]
    }
};

执行webpack之后,目录结构变成如下:

template5

改变a.css之后再执行webpack

发现文件目录变成如下:

template5

从目录可以看出,文件打包没有打包出css文件,而且只要修改a.css,那么a.js也会发生改变,所以chunkhash在含有css依赖的时候就会有问题

contenthash

webpack配置修改如下:

const extractTextPlugin = require('extract-text-webpack-plugin');
const webpack = require('webpack');

module.exports = {
    entry: {
        'a': './a',
        'b': './b'
    },

    output:{
        filename:'[name]-[chunkhash].js'
    },
    module: {
        loaders: [{
            test: /\.css$/,
            loader: extractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
        }],
    },
    plugins: [
        // 这里的 contenthash 是 ExtractTextPlugin 根据抽取输出的文件内容计算得到
        new extractTextPlugin('[name].[contenthash:4].css'),
    ],
}

执行webpack后的文件目录:

template5

然后改变a.css 文件之后,再执行webpack,可以看到文件目录如下:

template5

看到目录下只是生成了改变的新的css文件,达到目的.

使用webpackMd5Hash插件

webpack的配置如下:

const webpack = require('webpack');
const extractTextPlugin = require('extract-text-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash')

module.exports = {
    entry: {
        'a': './a',
        'b': './b'
    },

    output:{
        filename:'[name]-[chunkhash].js'
    },
    module: {
        loaders: [{
            test: /\.css$/,
            loader: extractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
        }],
    },
    plugins: [
        new extractTextPlugin('[name].[contenthash:4].css'),
        new WebpackMd5Hash()
    ],
}

文件目录如下图所示:

template5

修改a.css之后,文件目录变成如下所示:

template5

可以看出,当a.css发生改变的时候,依赖它的其他文件并没有重新生成新的hash值,所以使用webpackMd5Hash也可以解决问题
webpackMd5Hash通过模块路径来排序chunk的所有依赖模块,并将这些排序后的模块源代码拼接,最后用MD5拼接后内容的chunkhash,
但是webpackMd5Hash有一些issue,有一些坑,具体可以参见这里还有这里

图片的hash问题

在文件中难免会用到图片,比如在文件目录中,a.css文件代码如下:

a{
    font-size:14px;
    background:url('./1.png') no-repeat;
}

a.js中的文件代码如下:

require('./1.png');
require('./a.css')
require('./b.js')
var a = 'this is a';

webpack配置如下:

const webpack = require('webpack');
const extractTextPlugin = require('extract-text-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash')

module.exports = {
    entry: {
        'a': './a',
        'b': './b'
    },

    output:{
        filename:'[name]-[chunkhash].js'
    },
    module: {
        loaders: [
            {
            test: /\.css$/,
            loader: extractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
            },
            {
                // 图片加载器,雷同file-loader,更适合图片,可以将较小的图片转成base64,减少http请求
                // 如下配置,将小于8192byte的图片转成base64码
                test: /\.(png|jpg|gif)$/,
                loader: 'url-loader?limit=1000&name=../images/[name].[ext]?[hash]',
            }
        ],
    },
    plugins: [
        new extractTextPlugin('[name].[contenthash:4].css'),
        new WebpackMd5Hash()
    ],
}

执行webpack之后,目录结构如下图所示:

template5

可以看出图片也有相对应的编译文件,当图片的大小小于1000时,就不会创建相应的imags目录,只有大于1000时才会生成。当该目录的cssjs发生改变的时候,也不会重新出现新的image

关于这方面的问题,也可以参考这篇文章

@SunShinewyf
Copy link
Owner Author

SunShinewyf commented May 5, 2017

之后也看到过其他的解决方案,特此更新

  • 使用NamedModulesPlugin,配置更新如下:
plugins: [
    new webpack.NamedModulesPlugin(),
  ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant