让 Webpack 将生成的哈希值输出到配置文件
Get Webpack to output the generated hash to a config file
这是我们项目使用的技术栈:
- Symfony 2.8†
- 树枝 1.24†
- AngularJS1.5†
- Webpack 1.12†
我们有一个问题,我们的 app.min.js
文件被缓存了,当我们进行需要新 app.min.js
文件的更改时,我们的客户通常会继续使用缓存文件而不是加载新文件,并且最终产生错误并不得不致电我们的支持台。
我研究了通过将文件内容的哈希值嵌入到 HTTP 请求中来解决此问题,然后让服务器使用重写规则提供原始文件。我已经将 [contenthash].
添加到 webpack.config.js
中的文件名(见下文)但是当我 运行 Webpack 时,它不会替换 [contenthash]
,而是创建一个具有该确切内容的文件名字.
module.exports = {
output: {
filename: 'app.min.[contenthash].js'
}
}
我希望发生的事情是:
- 输出文件仍称为
app.min.js
和 app.min.js.map
- 生成的地图文件
app.min.js.map
链接到 app.min.6b1900549fed191ccbe8.js
- Webpack 将哈希值保存在配置文件的某处
app_min_js_hash: '6b1900549fed191ccbe8'
- 我更改了 Twig 模板以包含如下哈希:
<script src="/dist/js/app.min.{{ app_min_js_hash }}.js"></script>
所以我还有几个问题没有解决:
如何让 Webpack 将哈希输出到配置文件
如何让Webpack用hash替换关键字
- 如何让 Webpack 创建没有哈希的文件名
我已经知道如何解决 rewrite 和 Twig 部分了。
根据链接问题 () 中的评论,我现在得到:
webpack.config.js
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpackMajorVersion = require('webpack/package.json').version.split('.')[0];
module.exports = {
console: true,
name: 'js',
entry: ['./src/base.js'],
output: {
path: '../web/dist/js/',
publicPath: '/dist/js/',
filename: 'app.min.[hash].js'
},
devtool: "source-map",
resolve : {
root : [path.join(__dirname, "src/")]
},
sassLoader: {
includePaths: './src/'
},
resolveLoader: {
root: __dirname+'/node_modules/',
modulesDirectories: [""]
},
jshint: {
esversion: 6
},
// Initialize module
preLoaders: [],
module: {
preLoaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'jshint-loader',
}
],
loaders: [{
// JS LOADER
// Reference: https://github.com/babel/babel-loader
// Transpile .js files using babel-loader
// Compiles ES6 and ES7 into ES5 code
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query: {
presets: ['es2015']
},
exclude: /node_modules/
}, {
// ASSET LOADER
// Reference: https://github.com/webpack/file-loader
// Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to output
// Rename the file using the asset hash
// Pass along the updated reference to your code
// You can add here any file extension you want to get copied to your output
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/,
loader: 'file'
}, {
// HTML LOADER
// Reference: https://github.com/webpack/raw-loader
// Allow loading html through js
test: /\.html$/,
loader: "ngtemplate?relativeTo=" + (path.resolve(__dirname, './src/')) + "/!html"
}, {
test: /\.scss$/,
loaders: ["style", "css", "sass"]
}],
resolve: {
// you can now require('file') instead of require('file.coffee')
extensions: ['', '.js', '.json', '.coffee']
}
},
plugins: [
new HtmlWebpackPlugin({
templateContent: function(params) {
return `
{% block jsAssets %}
${params.htmlWebpackPlugin.files.js.map(
file => `<script src="${file}"></script>`,
)}
{% endblock %}
{% block cssAssets %}
${params.htmlWebpackPlugin.files.css.map(
file => `<link rel="stylesheet" type="text/css" href="${file}">`,
)}
{% endblock %}`;
},
filename: '../../resources/templates/assets.html.twig',
inject: false,
// // The following settings are optional and only used for
// // demo purposes:
// meta: {
// charset: { charset: 'utf-8' },
// viewport: 'width=device-width, initial-scale=1'
// },
// minify: false
})
]
};
在 Twig 代码 {{ block("jsAssets", "assets.html.twig") }}
执行任何操作之前 use
生成的 Twig 模板是必要的。
树枝:
{% use 'HTMLBundle:Layout:assets.html.twig' %}
...
{{ block("jsAssets", "assets.html.twig") }}
...
所以现在剩下的唯一问题是如何每次都保持输出文件名相同,同时仍然生成散列。否则,该目录将不断填满不同的散列版本(不是很小)。只需要最新的文件。我们使用一步部署,因此每次生成文件时都必须手动重命名文件,这打破了这种模式。
† 我已经知道这个版本太旧了。短期内不会改变。
在 webpack 1 中它被称为 [hash]
。你不需要发明轮子。
HTMLWebpack 插件开箱即用,支持将散列注入 html(甚至 php 模板)
编辑:
您可以使用哈希作为查询字符串:
module.exports = {
console: true,
name: 'js',
entry: ['./src/base.js'],
output: {
path: '../web/dist/js/',
publicPath: '/dist/js/',
filename: 'app.min.js?[hash]'
},
}
或者您可以在自己的模板中的 js 文件名中添加散列。
new HtmlWebpackPlugin({
templateContent: function(params) {
return `
{% block jsAssets %}
${params.htmlWebpackPlugin.files.js.map(
file => {
const [filename, hash] = file.split('?');
const modifiedFileName = filename.replace('.min.js',
`${hash}.min.js`);
return `<script src="${modifiedFileName}"></script>`
}
)}
{% endblock %}
`
}),
这是我们项目使用的技术栈:
- Symfony 2.8†
- 树枝 1.24†
- AngularJS1.5†
- Webpack 1.12†
我们有一个问题,我们的 app.min.js
文件被缓存了,当我们进行需要新 app.min.js
文件的更改时,我们的客户通常会继续使用缓存文件而不是加载新文件,并且最终产生错误并不得不致电我们的支持台。
我研究了通过将文件内容的哈希值嵌入到 HTTP 请求中来解决此问题,然后让服务器使用重写规则提供原始文件。我已经将 [contenthash].
添加到 webpack.config.js
中的文件名(见下文)但是当我 运行 Webpack 时,它不会替换 [contenthash]
,而是创建一个具有该确切内容的文件名字.
module.exports = {
output: {
filename: 'app.min.[contenthash].js'
}
}
我希望发生的事情是:
- 输出文件仍称为
app.min.js
和app.min.js.map
- 生成的地图文件
app.min.js.map
链接到app.min.6b1900549fed191ccbe8.js
- Webpack 将哈希值保存在配置文件的某处
app_min_js_hash: '6b1900549fed191ccbe8'
- 我更改了 Twig 模板以包含如下哈希:
<script src="/dist/js/app.min.{{ app_min_js_hash }}.js"></script>
所以我还有几个问题没有解决:
如何让 Webpack 将哈希输出到配置文件如何让Webpack用hash替换关键字- 如何让 Webpack 创建没有哈希的文件名
我已经知道如何解决 rewrite 和 Twig 部分了。
根据链接问题 (
webpack.config.js
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpackMajorVersion = require('webpack/package.json').version.split('.')[0];
module.exports = {
console: true,
name: 'js',
entry: ['./src/base.js'],
output: {
path: '../web/dist/js/',
publicPath: '/dist/js/',
filename: 'app.min.[hash].js'
},
devtool: "source-map",
resolve : {
root : [path.join(__dirname, "src/")]
},
sassLoader: {
includePaths: './src/'
},
resolveLoader: {
root: __dirname+'/node_modules/',
modulesDirectories: [""]
},
jshint: {
esversion: 6
},
// Initialize module
preLoaders: [],
module: {
preLoaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'jshint-loader',
}
],
loaders: [{
// JS LOADER
// Reference: https://github.com/babel/babel-loader
// Transpile .js files using babel-loader
// Compiles ES6 and ES7 into ES5 code
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query: {
presets: ['es2015']
},
exclude: /node_modules/
}, {
// ASSET LOADER
// Reference: https://github.com/webpack/file-loader
// Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to output
// Rename the file using the asset hash
// Pass along the updated reference to your code
// You can add here any file extension you want to get copied to your output
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/,
loader: 'file'
}, {
// HTML LOADER
// Reference: https://github.com/webpack/raw-loader
// Allow loading html through js
test: /\.html$/,
loader: "ngtemplate?relativeTo=" + (path.resolve(__dirname, './src/')) + "/!html"
}, {
test: /\.scss$/,
loaders: ["style", "css", "sass"]
}],
resolve: {
// you can now require('file') instead of require('file.coffee')
extensions: ['', '.js', '.json', '.coffee']
}
},
plugins: [
new HtmlWebpackPlugin({
templateContent: function(params) {
return `
{% block jsAssets %}
${params.htmlWebpackPlugin.files.js.map(
file => `<script src="${file}"></script>`,
)}
{% endblock %}
{% block cssAssets %}
${params.htmlWebpackPlugin.files.css.map(
file => `<link rel="stylesheet" type="text/css" href="${file}">`,
)}
{% endblock %}`;
},
filename: '../../resources/templates/assets.html.twig',
inject: false,
// // The following settings are optional and only used for
// // demo purposes:
// meta: {
// charset: { charset: 'utf-8' },
// viewport: 'width=device-width, initial-scale=1'
// },
// minify: false
})
]
};
在 Twig 代码 {{ block("jsAssets", "assets.html.twig") }}
执行任何操作之前 use
生成的 Twig 模板是必要的。
树枝:
{% use 'HTMLBundle:Layout:assets.html.twig' %}
...
{{ block("jsAssets", "assets.html.twig") }}
...
所以现在剩下的唯一问题是如何每次都保持输出文件名相同,同时仍然生成散列。否则,该目录将不断填满不同的散列版本(不是很小)。只需要最新的文件。我们使用一步部署,因此每次生成文件时都必须手动重命名文件,这打破了这种模式。
† 我已经知道这个版本太旧了。短期内不会改变。
在 webpack 1 中它被称为 [hash]
。你不需要发明轮子。
HTMLWebpack 插件开箱即用,支持将散列注入 html(甚至 php 模板)
编辑:
您可以使用哈希作为查询字符串:
module.exports = {
console: true,
name: 'js',
entry: ['./src/base.js'],
output: {
path: '../web/dist/js/',
publicPath: '/dist/js/',
filename: 'app.min.js?[hash]'
},
}
或者您可以在自己的模板中的 js 文件名中添加散列。
new HtmlWebpackPlugin({
templateContent: function(params) {
return `
{% block jsAssets %}
${params.htmlWebpackPlugin.files.js.map(
file => {
const [filename, hash] = file.split('?');
const modifiedFileName = filename.replace('.min.js',
`${hash}.min.js`);
return `<script src="${modifiedFileName}"></script>`
}
)}
{% endblock %}
`
}),