通过Webpack创建一个带有hash的供应商bundle,并在同构应用程序中使用它



我有三种不同的Webpack配置(client.Webpack.js、server.webpackjs和vendor.Webpack.js(vendor.web pack.js用于创建供应商捆绑包,因为它们很少更改,而且占用大量空间。我们使用DllPlugin来生成它,并通过DllReferencePlugin在client.webpack.js中使用生成的manifest.json。

我想做的改进是在供应商文件中添加一个散列,例如,我想创建vendor.348723.js而不是vendor.js。原因是为了改进缓存。

棘手的部分是,我们的应用程序是同构的,这意味着HTML的生成是由服务器(Node.js+Rreact,server.webpack.js(在运行时完成的。在服务器内部,在一个JS文件中,我们创建了模板,其中有<script type='text/javascript' src='/vendor.js'></script>。我的问题是,如何注入供应商。有人在那里吗?

我尝试过但失败了:

扩展API插件

使用Webpack缓存,索引源代码中的[哈希]值,使用React.js

在vendor.webpack.js中使用ExtendedAPIPlugin,并在生成HTML模板时尝试使用__webpack_hash__,例如<script type='text/javascript' src='/vendor.${__webpack_hash__}.js'></script>由于我有两种不同的Webpack配置,并且我在vendor.Webpack.js中生成哈希,因此在生成HTML模板时服务器无法识别它。

其他相关信息

我们不使用html webpack插件——我认为它不适用,因为我们有一个同构的应用程序。(Webpack-更新HTML以包含最新[哈希]捆绑包的最佳方式(

我查看的其他相关页面

在提取文本插件之后,将css文件名与hash链接到index.html

vendor.webpack.js

const path = require('path')
const webpack = require('webpack')
module.exports = {
name: 'vendor',
mode: 'development',
entry: [
'axios',
'babel-polyfill',
'material-ui',
'classnames',
'mixpanel-browser',
'ramda',
'react',
'react-dropzone-component',
'react-dom',
'react-ga',
'react-helmet',
'react-redux',
'react-router-dom',
'react-router-redux',
'redux',
'redux-thunk',
'redux-saga'
],
output: {
path: path.resolve(__dirname, '../client'),
filename: 'vendor.js',
library: 'vendor_[hash]'
},
plugins: [
new webpack.DllPlugin({
name: 'vendor_[hash]',
path: path.resolve(__dirname, '../client/manifest.json')
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV)
}
}),
new webpack.ExtendedAPIPlugin(),
new webpack.IgnorePlugin(/^./locale$/, /moment$/)
]
}

client.webpack.js

require('env2')('env.json')
const path = require('path')
const webpack = require('webpack')
const StatsPlugin = require('stats-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const merge = require('webpack-merge')
const baseConfig = require('./base.js')
module.exports = merge(baseConfig.moduleRules, {
name: 'client',
mode: 'development',
target: 'web',
// Good compromise between speed and quality, suitable for local development.
devtool: 'cheap-module-eval-source-map',
entry: [path.resolve(__dirname, '../app/index.js')],
output: {
filename: 'client.[chunkhash].js',
chunkFilename: 'client.[chunkhash].js',
path: path.resolve(__dirname, '../client'),
publicPath: '/'
},
watchOptions: {
poll: true
},
plugins: [
new MiniCssExtractPlugin({
filename: 'style.css'
}),
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, '../client/manifest.json')
}),
new StatsPlugin('stats.json'),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development')
}
})
],
optimization: {
runtimeChunk: 'single'
}
})

server.webpack.js

const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const merge = require('webpack-merge')
const baseConfig = require('./base.js')
const res = p => path.resolve(__dirname, p)
const modeModules = res('../node_modules')
const entry = res('../lib/routes/resources/reactUrls.js')
const output = res('../buildServer')
// if you're specifying externals to leave unbundled, you need to tell Webpack
// to still bundle `react-universal-component`, `webpack-flush-chunks` and
// `require-universal-module` so that they know they are running
// within Webpack and can properly make connections to client modules:
const externals = fs
.readdirSync(modeModules)
.filter(x => !/.bin|react-universal-component|webpack-flush-chunks/.test(x))
.reduce((externals, mod) => {
externals[mod] = `commonjs ${mod}`
return externals
}, {})
externals['react-dom/server'] = 'commonjs react-dom/server'
module.exports = merge(baseConfig.commons, {
name: 'server',
mode: 'development',
target: 'node',
// Good compromise between speed and quality, suitable for local development.
devtool: 'cheap-module-eval-source-map',
entry: [entry],
externals,
output: {
path: output,
filename: '[name].js',
libraryTarget: 'commonjs2'
},
plugins: [
new MiniCssExtractPlugin({
filename: '/style.css'
}),
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1
}),
new webpack.EnvironmentPlugin(['NODE_ENV'])
]
})

WebpackManifestPluin可以用来解决这个问题。

最新更新