如何使用Webpack DevServer运行dist目录外的index.html
问题与解决方案
问题背景
除dist目录外,项目还有dev目录存放测试用的index.html,该文件引用dist下的CSS和JS。项目目录结构如下:
|-- dev |-- index.html |-- dist |-- scroll.carousel.js |-- scroll.carousel.css |-- src |-- js |-- index.js |-- other.js |-- scss |-- style.scss
index.html内容:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Document</title> <link rel="stylesheet" href="../dist/scroll.carousel.css"> </head> <body> <h1>Hello world</h1> <script src="../dist/scroll.carousel.js"></script> </body> </html>
遇到的问题
- 运行DevServer时无法加载CSS样式
- 修改
src目录文件时,DevServer不自动刷新浏览器
当前webpack.config.js配置:
const path = require('path'); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts'); module.exports = { mode: "production", target: 'web', entry: { ["scroll.carousel"]: './src/js/index.js', ["scroll.carousel.style"]: './src/scss/style.scss', }, output: { path: path.resolve(__dirname, 'dist'), publicPath: "/", clean: true }, plugins: [ new RemoveEmptyScriptsPlugin(), new MiniCssExtractPlugin({ filename: (pathData) => { if (pathData.chunk.name.includes(".style")) { return pathData.chunk.name.replace(".style", "") + ".css" } return '[name].css' }, }), ], module: { rules: [ { test: /\.s[ac]ss$/i, use: [ // Extract CSS MiniCssExtractPlugin.loader, // Translates CSS into CommonJS { loader: 'css-loader', options: { sourceMap: true, url: false } }, // Compiles Sass to CSS { loader: 'sass-loader', options: { sourceMap: true } } ], }, ], }, devtool: 'source-map', devServer: { static: { directory: path.resolve(__dirname, 'dev'), watch: true, }, watchFiles: ["./src/**/*"], open: true, liveReload: true }, };
解决方案
1. 修复CSS加载失败问题
DevServer默认只把dev目录作为静态资源根目录,../dist/的路径在DevServer的服务上下文下无法被解析。
修改步骤:
- 在
devServer.static中添加dist目录作为静态资源目录,让DevServer能访问到该目录下的文件 - 调整
index.html中的资源引用路径,去掉../dist/前缀,直接使用文件名,因为DevServer会把dist目录的内容映射到根路径
修改后的devServer配置片段:
devServer: { static: [ { directory: path.resolve(__dirname, 'dev'), watch: true, }, { directory: path.resolve(__dirname, 'dist'), watch: true, } ], // ...其他配置 },
修改后的index.html引用:
<link rel="stylesheet" href="scroll.carousel.css"> <script src="scroll.carousel.js"></script>
2. 修复自动刷新问题
当前配置使用mode: "production",生产模式下Webpack的优化策略会降低文件监听的灵敏度,同时output.clean: true会在每次编译清空dist目录,可能影响DevServer的资源访问。
修改步骤:
- 将
mode改为development,开发模式下Webpack会保留更多调试信息,文件监听更灵敏 - 注释掉
output.clean: true,避免每次编译清空dist目录 - 扩展
watchFiles包含dev目录的文件(如果需要修改index.html时也触发刷新) - 更换
devtool为eval-cheap-module-source-map,开发环境下构建速度更快
修改后的完整webpack.config.js:
const path = require('path'); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts'); module.exports = { mode: "development", target: 'web', entry: { ["scroll.carousel"]: './src/js/index.js', ["scroll.carousel.style"]: './src/scss/style.scss', }, output: { path: path.resolve(__dirname, 'dist'), publicPath: "/", // clean: true, 开发环境注释,避免频繁清空dist }, plugins: [ new RemoveEmptyScriptsPlugin(), new MiniCssExtractPlugin({ filename: (pathData) => { if (pathData.chunk.name.includes(".style")) { return pathData.chunk.name.replace(".style", "") + ".css" } return '[name].css' }, }), ], module: { rules: [ { test: /\.s[ac]ss$/i, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { sourceMap: true, url: false } }, { loader: 'sass-loader', options: { sourceMap: true } } ], }, ], }, devtool: 'eval-cheap-module-source-map', devServer: { static: [ { directory: path.resolve(__dirname, 'dev'), watch: true, }, { directory: path.resolve(__dirname, 'dist'), watch: true, } ], watchFiles: ["./src/**/*", "./dev/**/*"], open: true, liveReload: true, hot: false, // 使用MiniCssExtractPlugin时关闭HMR,依赖liveReload即可 }, };
内容的提问来源于stack exchange,提问作者Asif Jalil
相关产品推荐
相关产品推荐

