我的网络包入口点名称中包含[hash]
:
entry: "index.js",
output: {
path: "build/",
filename: "index-[hash].js",
}
如何直接从我的应用程序的HTML链接到该入口点?
例如,我希望发送给客户的HTML包括:
<script src="build/index-41d40fe7b20ba1dce81f.js"></script>
我该怎么做?是否有一个插件可以生成一个入口点清单,我的应用程序可以读取并发出相应的文件名?
答案 0 :(得分:25)
html-webpack-plugin(我是作者)将生成一个index.html,用于引用正确的散列包文件名。
var HtmlWebpackPlugin = require("html-webpack-plugin");
var webpackConfig = {
entry: "index.js",
output: {
path: "build/",
filename: "index-[hash].js",
},
plugins: [new HtmlWebpackPlugin()]
}
这会产生build/index.html
,其中包含带有<script>
标记的捆绑包。
答案 1 :(得分:8)
我刚刚开始玩webpack,并且发现gulp非常适合将新散列的js文件写入index.html。如果您不想使用gulp,this discussion regarding doing something similar with a plugin可能会有所帮助。这是一个gulpfile片段,也可能有所帮助:
var util = require('util');
var path = require('path');
var gulp = require('gulp');
var runSequence = require('run-sequence');
var rimraf = require('rimraf');
var gzip = require('gulp-gzip');
var notify = require('gulp-notify');
var gutil = require('gulp-util');
var webpack = require('webpack');
var webpackConfig = require('./client/webpack.config');
var through2 = require('through2');
gulp.task("webpack", function (cb) {
webpack(webpackConfig, function (err, stats) {
if (err) throw new gutil.PluginError("webpack", err);
var jsFilename = stats.toJson().assetsByChunkName['app'];
console.log('>>>>', jsFilename);
// if source-maps are turned on, you'll get [ 'somefile.js', 'somefile.js.map' ]
if (util.isArray(jsFilename)) {
jsFilename = jsFilename.filter(function (filename) {
return path.extname(filename).toLowerCase() === '.js'
}).shift();
}
// write the hashed main.js to /dist/index.html
gulp.src('./client/index.html')
.on('error', handleErrors)
.pipe(through2.obj(function (vinylFile, enc, tCb) {
vinylFile.contents = new Buffer(String(vinylFile.contents)
.replace('main.js', jsFilename));
this.push(vinylFile);
tCb();
}))
.pipe(gulp.dest('./dist/'));
cb();
});
});
function handleErrors() {
var args = Array.prototype.slice.call(arguments);
notify.onError({ title: 'Error', message: '<%= error.message %>'}).apply(this, args);
this.emit('end');
}
gulp.task('gzip-deploy', function () {
return gulp.src('./dist/**/*')
.on('error', handleErrors)
.pipe(gzip())
.pipe(gulp.dest('./dist/'));
});
gulp.task('clean', function (cb) {
return rimraf('./dist', cb);
});
gulp.task('default', function (cb) {
runSequence('clean', 'webpack', cb);
});
gulp.task('deploy', function (cb) {
webpackConfig.plugins = webpackConfig.plugins = [
new webpack.optimize.UglifyJsPlugin(),
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production")
}
})
];
webpackConfig.watch = false;
webpackConfig.devtool = null;
webpackConfig.output.filename = "main-[hash].js";
runSequence('clean', 'webpack', 'gzip-deploy', cb);
});
这里是我的webpack.config.js
文件以及一些上下文:
var path = require('path');
module.exports = {
context: __dirname,
devtool: 'source-map',
entry: {
app: './main.js'
},
watch: true,
output: {
path: path.join(__dirname, "/../dist"),
filename: "main.js"
},
module: {
loaders: [
{ test: /\.js$/, loader: 'jsx-loader?harmony' },
{ test: /\.css$/, loader: "style-loader!css-loader" },
{ test: /\.less$/, loader: "style-loader!css-loader!less-loader" },
{ test: /\.png$/, loader: "url-loader?prefix=img/&limit=8192" },
{ test: /\.jpg$/, loader: "url-loader?prefix=img/&limit=8192" },
{ test: /\.gif$/, loader: "url-loader?prefix=img/&limit=8192" },
{ test: /\.woff$/, loader: "url-loader?prefix=font/&limit=8192" },
{ test: /\.eot$/, loader: "file-loader?prefix=font/" },
{ test: /\.ttf$/, loader: "file-loader?prefix=font/" },
{ test: /\.svg$/, loader: "file-loader?prefix=font/" }
]
},
resolve: {
extensions: ['', '.js', '.json'],
modulesDirectories: ['node_modules']
},
plugins: []
};