如何在Webpack编译中排除指定Vue.js组件与TS文件?
问题:Laravel+Vue项目中排除指定目录的编译
项目环境与需求
- 技术栈:Laravel + Vue.js 2
- 构建命令:
npm run dev npm run watch npm run production - 当前编译范围:
project/resources/assets/components/下所有子模块(包含.vue和.ts文件) - 核心需求:执行构建命令时,阻止编译以下目录的所有文件:
project/resources/assets/components/module1/ project/resources/assets/components/module2/
现有配置文件
webpack.config.js
const path = require("path"); const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); const report = process.env.npm_config_report; const time = process.env.npm_config_time; let plugins = [ new ForkTsCheckerWebpackPlugin({ typescript: { extensions: { vue: true } } }), ]; if (report) { plugins.push( new BundleAnalyzerPlugin({ openAnalyzer: true, }) ); } let webpackConfig = { resolve: { extensions: [".js", ".vue", ".json", ".ts"], fallback: { path: require.resolve("path-browserify") }, alias: { vue$: "vue/dist/vue.esm.js", src: path.join(__dirname, "resources/assets"), assets: path.join(__dirname, "resources/assets/assets"), components: path.join(__dirname, "resources/assets/components"), helpers: path.join(__dirname, "resources/assets/helpers"), pages: path.join(__dirname, "resources/assets/components/pages"), img: path.join(__dirname, "resources/assets/assets/img"), custom_fonts: path.join( __dirname, "resources/assets/assets/custom_fonts" ), }, symlinks: false, }, optimization: { splitChunks: { chunks: "all", }, runtimeChunk: true, }, module: { rules: [ { test: /\.tsx?$/, loader: "ts-loader", exclude: /node_modules/, options: { appendTsSuffixTo: [/\.vue$/], transpileOnly: true, }, }, { test: /\.vue$/, loader: "vue-loader", exclude: path.resolve( __dirname, "resources/assets/components/module1" ), }, ], }, cache: true, plugins, }; if (time) { const smp = new SpeedMeasurePlugin(); webpackConfig = smp.wrap(webpackConfig); } module.exports = webpackConfig;
webpack.mix.js
let mix = require("laravel-mix"); const config = require("./webpack.config"); /* |-------------------------------------------------------------------------- | Mix Asset Management |-------------------------------------------------------------------------- | | Mix provides a clean, fluent API for defining some Webpack build steps | for your Laravel application. By default, we are compiling the Sass | file for the application as well as bundling up all the JS files. | */ const report = process.env.npm_config_report; mix.webpackConfig({ ...config, output: { chunkFilename: mix.inProduction() ? "js/[id].[chunkhash].js" : "dev/js/[id].js", }, }); if (!report) { //hide chunk complete list mix.after((stats) => { stats.compilation.assets = {}; }); } mix .ts("resources/assets/main.ts", mix.inProduction() ? "public/" : "public/dev/") .vue({ version: 2 }) .extract([ "vue", "vuex", "vuex-persistedstate", "axios", "vue-router", "vue-form-wizard", "vue-sweetalert2", "vue-inputmask", "vue-data-tables", "vue-moment", "vue2-dropzone", "vue-html2canvas", "vuedraggable", "inputmask", "element-ui", "jspdf", "normalize.css", "v-money", "xlsx", ]) .options({ postCss: [require("autoprefixer")], }); if (mix.inProduction()) { mix.version(); } else { mix.override((webpackConfig) => { webpackConfig.devtool = "eval-cheap-source-map"; // Fastest for development }); } // Disable all OS notifications mix.disableNotifications();
已尝试的无效方案
- 排除单个.ts文件:修改ts-loader的exclude规则添加指定文件路径,但修改该文件时
npm run watch仍会触发编译{ test: /\.ts?$/, loader: "ts-loader", exclude: [ /node_modules/, path.join(__dirname, "resources/assets/components/mvp/rules.ts"), ], options: { appendTsSuffixTo: [/\.vue$/], transpileOnly: true, }, } - 排除单个目录的.vue文件:修改vue-loader的exclude规则指定module1路径,但修改该目录下组件模板时仍会触发编译
{ test: /\.vue$/, loader: "vue-loader", exclude: path.resolve( __dirname, "resources/assets/components/module1" ), }
解决方案
1. 完善Webpack规则的排除逻辑
需要同时针对.ts、.vue文件配置全局排除,并且确保类型检查插件也忽略这些目录:
// 修改webpack.config.js中的module.rules module: { rules: [ { test: /\.tsx?$/, loader: "ts-loader", exclude: [ /node_modules/, // 匹配module1/module2下所有.ts文件 /resources\/assets\/components\/(module1|module2)\/.*\.ts$/ ], options: { appendTsSuffixTo: [/\.vue$/], transpileOnly: true, }, }, { test: /\.vue$/, loader: "vue-loader", exclude: [ path.resolve(__dirname, "resources/assets/components/module1"), path.resolve(__dirname, "resources/assets/components/module2") ], }, ], }, // 修改ForkTsCheckerWebpackPlugin配置 plugins: [ new ForkTsCheckerWebpackPlugin({ typescript: { extensions: { vue: true }, exclude: [ "resources/assets/components/module1/**/*", "resources/assets/components/module2/**/*" ] } }), // 其他插件... ]
2. 阻止Laravel Mix监听排除目录
在webpack.mix.js的webpackConfig中添加watch忽略规则,避免watch模式下触发不必要的构建:
mix.webpackConfig({ ...config, output: { chunkFilename: mix.inProduction() ? "js/[id].[chunkhash].js" : "dev/js/[id].js", }, watchOptions: { ignored: [ path.resolve(__dirname, "resources/assets/components/module1/**/*"), path.resolve(__dirname, "resources/assets/components/module2/**/*") ] } });
3. 清理入口文件的依赖引用
检查main.ts及其他入口文件,确保没有import module1/module2下的组件或文件,否则Webpack仍会强制编译这些依赖模块。
验证方法
- 运行
npm run watch,修改module1/module2下的.vue或.ts文件,确认不会触发编译 - 运行
npm run production,检查输出产物,确认排除目录的代码未被打包
内容的提问来源于stack exchange,提问作者JG_GJ
相关产品推荐
相关产品推荐

