我有一个标准的文件夹结构,有点像这样:
.
├── dist
| ├── vendor.js
| └── app.js
| └── index.html
├── src
| └── index.html
| └── entry.js // main app entry file
| └── entry-client.js // for client hydration
| └── entry-server.js // for server-side rendering
| └── server.js
├── package.json
整个dist
文件夹由 webpack 构建,包括index.html
刚刚从文件夹中复制的src
文件。当我想在开发环境中运行时,该文件index.html
需要客户端水合才能工作。如果它们不存在,那么只有服务器端呈现的页面会通过。这样做的问题是,如果不在每次文件更改时完全重建文件夹,我就无法进行任何开发工作,这需要很长时间,而且是一种完全低效的开发方式。/dist/app.js
/dist/vendor.js
dist
我的 webpack 客户端构建配置是这样的:
const webpack = require('webpack');
const merge = require('webpack-merge');
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const utils = require('./utils') // just resolves directories/files paths
const baseConfig = require('./webpack.base.config');
const isProduction = process.env.NODE_ENV === 'production';
module.exports = merge(baseConfig, {
entry: {
app: utils.resolve('/src/entry-client.js')
},
output: {
path: utils.resolve('/dist'),
filename: '[name].js', // generates app.js in ./dist folder
sourceMapFilename: '[name].js.map',
},
resolve: {
extensions: ['.js', '.vue'],
},
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: "vendor", // generates vendor.js file in ./dist
chunks: "all",
},
},
},
},
module: {
rules: [
{
test: /\.css?$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
sourceMap: !isProduction,
// only enable hot in development
hmr: !isProduction,
// if hmr does not work, this is a forceful method.
reloadAll: true,
},
},
'css-loader',
]
},
plugins:
(isProduction ?
[
new MiniCssExtractPlugin({
filename: 'assets/css/site.css',
}),
] : [
new MiniCssExtractPlugin({
filename: 'assets/css/site.css',
hmr: true,
}),
new webpack.HotModuleReplacementPlugin(),
]
)
});
以上仅在我执行时运行npm run build:client
。我的开发设置是这样的:
/**
* Setup webpack-dev-middleware and webpack-hot-middleware.
* Rebuild SSR bundle on src files change.
*
* @param {Object} app Express application
* @param {Function} onServerBundleReady Callback
*/
const setupDevServer = (app, onServerBundleReady) => {
const webpack = require('webpack');
const MFS = require('memory-fs');
const path = require('path');
const clientConfig = require('./webpack.client.config');
const serverConfig = require('./webpack.ssr.config');
// additional client entry for hot reload
clientConfig.entry.app = ['webpack-hot-middleware/client', clientConfig.entry.app];
const clientCompiler = webpack(clientConfig);
// setup dev middleware
app.use(require('webpack-dev-middleware')(clientCompiler, {
publicPath: clientConfig.output.publicPath,
serverSideRender: true,
logLevel: 'silent'
}));
// setup hot middleware
app.use(require('webpack-hot-middleware')(clientCompiler));
// watch src files and rebuild SSR bundle
global.console.log('Building SSR bundle...');
const serverCompiler = webpack(serverConfig);
const mfs = new MFS();
serverCompiler.outputFileSystem = mfs;
serverCompiler.watch({}, (error, stats) => {
if (error) throw error;
global.console.log(
`${stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false,
})}\n\n`
);
if (stats.hasErrors()) {
console.error(stats.compilation.errors);
throw new Error(stats.compilation.errors);
}
// read bundle generated by vue-ssr-webpack-plugin
const bundle = JSON.parse(
mfs.readFileSync(path.join(clientConfig.output.path, 'vue-ssr-server-bundle.json'), 'utf-8')
);
onServerBundleReady(bundle);
});
};
module.exports = setupDevServer;
上面的配置永远不会在更改任何其他文件时setup-dev-server.js
重建文件夹中的app.js
或vendor.js
文件,这意味着开发模式毫无意义。./dist
我该如何解决这个问题,以便Home.vue
对例如的任何更改都会触发重新创建,app.js
因此vendor.js
我的更新实际上可以工作?