Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.3k views
in Technique[技术] by (71.8m points)

vue-cli-service build --mode test 的打包的时候会将process 相关代码打进去

这是我的vue.config.js配置

let webpack = require('webpack')
let CopyWebpackPlugin = require("copy-webpack-plugin");
let ZipPlugin = require("zip-webpack-plugin");
let path = require("path");
let buildConfig = require("./buildConfig");
let shell = require('shelljs');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const LodashModuleReplacementPlugin = require("lodash-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const FileManagerPlugin = require('filemanager-webpack-plugin');
const IS_PRODUCTION = process.env.NODE_ENV === 'production';
const IS_DEVELOPMENT = process.env.NODE_ENV === 'development';
console.log(process.env.NODE_ENV)
// 删除.zip包 并讲static里的资源copy至dist
var assetsPath = path.join(buildConfig.build.assetsRoot, buildConfig.build.assetsSubDirectory)
shell.rm('-rf', assetsPath)
shell.rm('-rf', '*.zip', path.resolve(__dirname, '../*.zip'));
shell.mkdir('-p', assetsPath)
shell.config.silent = true
shell.cp('-R', 'static/*', assetsPath)
shell.config.silent = false;
let exportConfig = {
    assetsDir: 'static',
 publicPath: './',
 productionSourceMap: IS_PRODUCTION !== true,
 configureWebpack: () => {
        const plugins = [];
 plugins.push(new HtmlWebpackPlugin({
            filename: path.join(__dirname, './dist/index.html'),
 template: 'index.html',
 inject: true,
 templateParameters(compilation, assets, options) {
                return {
                    compilation: compilation,
 webpack: compilation.getStats().toJson(),
 webpackConfig: compilation.options,
 htmlWebpackPlugin: {
                        files: assets,
 options: options
                    },
 process,
 };
 },
 minify: {
                removeComments: true,
 collapseWhitespace: true,
 removeAttributeQuotes: true
 // more options:
 // https://github.com/kangax/html-minifier#options-quick-reference },
 // necessary to consistently work with multiple chunks via CommonsChunkPlugin
 chunksSortMode: 'auto'
 }));
 if (process.env.NODE_ENV === "production") {
            plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            // warnings: false,
 drop_console: true,
 pure_funcs: ["console.log"] //移除console
 }
                    },
 sourceMap: false,
 parallel: true
 })
            );
 // 按需加载
 plugins.push(LodashModuleReplacementPlugin);
 }
        // 设置全局变量
 let ENV_TYPE, CONF = path.resolve(__dirname, './src/projectConfig.js');
 switch (process.env.NODE_ENV) {
            case 'development':
                ENV_TYPE = path.resolve(__dirname, './buildConfig/dev.env.js');
 break; case 'test':
                ENV_TYPE = path.resolve(__dirname, './buildConfig/test.env.js');
 break; case 'production':
                ENV_TYPE = path.resolve(__dirname, './buildConfig/prod.env.js');
 break }
        plugins.push(new webpack.ProvidePlugin({
            '$envType': ENV_TYPE,
 '$conf': [CONF, 'default']
        }));
 if (!IS_DEVELOPMENT) {
            let CopyWebpackPluginObj = [
                {
                    from: path.join(__dirname, './CubeModule.json'),
 to: path.join(__dirname, './dist/CubeModule.json'),
 transform: function (content, path) {
                        if (!IS_PRODUCTION) {
                            // 对调版本号
 const cubeModule = JSON.parse(content)
                            var temp = {
                                version: cubeModule.version,
 build: cubeModule.build
 }
                            for (var p in temp) {
                                cubeModule[p] = cubeModule['test' + p[0].toUpperCase() + p.slice(1)]
                                cubeModule['test' + p[0].toUpperCase() + p.slice(1)] = temp[p]
                            }
                            return new Buffer.from(JSON.stringify(cubeModule))
                        } else {
                            return new Buffer.from(content)
                        }
                    }
                },
 {
                    from: path.join(__dirname, './static'),
 to: path.join(__dirname, './dist/static/'),
 }
            ];
 plugins.push(new CopyWebpackPlugin({patterns: CopyWebpackPluginObj}));
 plugins.push(new FileManagerPlugin({
                events: {
                    onEnd: {
                        archive: [
                            {
                                source: './dist',
 destination: './' + IS_PRODUCTION === true ? buildConfig.build.zipName : buildConfig.buildTest.zipName
 },
 ]
                    }
                }
            }));
 // plugins.push(new ZipPlugin({
 //     path: path.join(__dirname, './'), //     filename: IS_PRODUCTION === true ? buildConfig.build.zipName : buildConfig.buildTest.zipName, // })); if (process.env.npm_config_report) {
                // 打包后模块大小分析//npm run build --report
 plugins.push(new BundleAnalyzerPlugin());
 }
        }
        return {
            plugins: plugins
        }
    },
 chainWebpack: (webpackConfig) => {
        // 删除预加载
 // webpackConfig.plugins.delete('preload'); // webpackConfig.plugins.delete('prefetch'); // todo 按理说这个应该是不需要了
 webpackConfig
            .entry('./src/main.js')
            .add('@babel/polyfill')
            .end();
 /*设置资源夹路径*/
 webpackConfig.resolve
 .alias
 .set("assets", path.join(__dirname, "src/assets"))
            .set("$common", path.join(__dirname, "src/js/common.js"))
            .set('@', path.join(__dirname, 'src'))
            .set("@assets", "@/assets")
            .set("@components", "@/components")
            .set("@css", "@/assets/style")
            .set("@img", "@/assets/images")
            .set("@store", "@/store");
 /*设置资源夹路径*/
 webpackConfig.resolve
 .extensions
 .add('.js').add('.vue').add('.json');
 // 压缩图片
 webpackConfig.module
 .rule("images")
            .use("image-webpack-loader")
            .loader("image-webpack-loader")
            .options({
                mozjpeg: {
                    progressive: true,
 quality: 65
 },
 optipng: {
                    enabled: false
 },
 pngquant: {
                    quality: [0.65, 0.90],
 speed: 4
 },
 gifsicle: {
                    interlaced: false
 }
            })
            .tap(options => Object.assign(options, { limit: 2040 }));
 // 处理mp3
 webpackConfig.module
 .rule("mp3")
            .test(/.(mp3)$/)
            .use("file-loader")
            .loader("file-loader")
            .end();
 // webpackConfig.module
 //     .rule('js') //     .test(/.js$/) //     .exclude //     .add('/node_modules/') if (IS_PRODUCTION) {
            // 代码压缩
 webpackConfig.optimization.minimize(IS_PRODUCTION);
 //分割代码
 webpackConfig.optimization.splitChunks({
                chunks: 'all'
 })
        }
        webpackConfig.devtool(IS_PRODUCTION === true ? false : "source-map");
 },
 css: {
        extract: IS_DEVELOPMENT !== true, // 是否使用css分离插件 ExtractTextPlugin  为true时不会热更新
 sourceMap: false, // 开启 CSS source maps?
 // 启用 CSS modules for all css / pre-processor files. requireModuleExtension: false,
 loaderOptions: {
            css: {
                // 这里的选项会传递给 css-loader
 },
 less: {
                // data: `@import "~@css/variable.less";`
 },
 postcss: {
                // 这里的选项会传递给 postcss-loader
 }
        }
    },
 // 是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
 parallel: require("os").cpus().length > 1,
 devServer: {
        port: 8080,
 open: false
 },
 // 第三方插件配置
 pluginOptions: {
        'style-resources-loader': {
            preProcessor: 'less',
 patterns: [
                // path.resolve(__dirname, 'src/assets/style/common.less'),
 // path.resolve(__dirname, 'src/assets/style/mixins.less'), // path.resolve(__dirname, 'src/assets/style/reset.less'), // path.resolve(__dirname, 'src/assets/style/variable.less'), ]
        }
    }
}
module.exports = exportConfig

这是package.json

{
 "version": "1.0.0",
 "private": true,
 "scripts": {
        "serve": "vue-cli-service serve",
 "build": "vue-cli-service build",
 "buildTest": "vue-cli-service build --mode test",
 "test:unit": "vue-cli-service test:unit",
 "lint": "vue-cli-service lint",
 "dev": "vue-cli-service serve"
 },
 "dependencies": {
 "axios": "^0.19.0",
 "core-js": "^3.6.5",
 "fastclick": "^1.0.6",
 "imagemin-mozjpeg": "^9.0.0",
 "lottie-web": "^5.7.3",
 "vue": "^2.6.11",
 "vue-awesome-swiper": "^3.1.3",
 "vue-router": "^3.2.0",
 "vue-swiper-component": "^2.1.3",
 "vuex": "^3.4.0"
 },
 "devDependencies": {
        "@babel/polyfill": "^7.11.5",
 "@babel/preset-env": "^7.11.5",
 "@babel/preset-react": "^7.10.4",
 "@vue/cli-plugin-babel": "^4.5.0",
 "@vue/cli-plugin-eslint": "^4.5.0",
 "@vue/cli-plugin-router": "^4.5.0",
 "@vue/cli-plugin-unit-mocha": "^4.5.0",
 "@vue/cli-plugin-vuex": "^4.5.0",
 "@vue/cli-service": "^4.5.0",
 "@vue/test-utils": "^1.0.3",
 "babel-eslint": "^10.1.0",
 "babel-loader": "^8.0.0-beta.0",
 "babel-plugin-import": "^1.13.1",
 "babel-plugin-istanbul": "^6.0.0",
 "chai": "^4.1.2",
 "copy-webpack-plugin": "^6.2.1",
 "eslint": "^6.7.2",
 "eslint-plugin-vue": "^6.2.2",
 "filemanager-webpack-plugin": "^3.0.0-alpha.7",
 "html-webpack-plugin": "^4.5.0",
 "image-webpack-loader": "^7.0.1",
 "less": "^3.0.4",
 "less-loader": "^5.0.0",
 "lodash-webpack-plugin": "^0.11.5",
 "promise": "^8.1.0",
 "qs": "^6.9.4",
 "shelljs": "^0.8.4",
 "uglifyjs-webpack-plugin": "1.1.6",
 "vconsole": "^3.3.4",
 "vue-template-compiler": "^2.6.11",
 "webpack-bundle-analyzer": "^3.9.0",
 "zip-webpack-plugin": "^3.0.0"
 }
}

报错提示:

Uncaught ReferenceError: process is not defined
/storage/emulated/0/Android/data/com.midea.out.css.test/files/www/com.midea.engineer.application.ms/cordova.js?ver=md5:314:13?ReferenceError: process is not defined
at u (file:///storage/emulated/0/Android/data/com.midea.out.css.test/files/www/com.midea.engineer.application.ms/static/js/app.js:1:285918)
at s (file:///storage/emulated/0/Android/data/com.midea.out.css.test/files/www/com.midea.engineer.application.ms/static/js/app.js:1:285692)
at file:///storage/emulated/0/Android/data/com.midea.out.css.test/files/www/com.midea.engineer.application.ms/static/js/app.js:1:739057
at l (file:///storage/emulated/0/Android/data/com.midea.out.css.test/files/www/com.midea.engineer.application.ms/static/js/app.js:1:739281)
at u (file:///storage/emulated/0/Android/data/com.midea.out.css.test/files/www/com.midea.engineer.application.ms/static/js/app.js:1:739729)
at c (file:///storage/emulated/0/Android/data/com.midea.out.css.test/files/www/com.midea.engineer.application.ms/static/js/app.js:1:739645)
at file:///storage/emulated/0/Android/data/com.midea.out.css.test/files/www/com.midea.engineer.application.ms/static/js/app.js:1:740037
at file:///storage/emulated/0/Android/data/com.midea.out.css.test/files/www/com.midea.engineer.application.ms/static/js/app.js:1:274361
at Object.callbackFromNative (file:///storage/emulated/0/Android/data/com.midea.out.css.test/files/www/com.midea.engineer.application.ms/cordova.js?ver=md5:293:58)
at <anonymous>:1:9

其实产生的原因应该是vue.config.js 里面某个js插件的影响,test环境下开启了sourcemap, 关闭了UglifyJsPlugin 插件,也关闭了optimization的minimize 和splitChunks

下面这个是打包代码里面出现process相关代码的截图
image

如果运行的是vue-cli-service build 也就是开启了相关js的压缩插件,process 就不会打进去。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

终于被自己找到答案了,自己埋的坑,跪着也要舔完
原因是有个模块引入了 import promise from 'promise' 但是这个promise却没有安装。然后这个模块使用了try catch,这样的话asap 就会把这个处理异常打进去。然而asap 这个处理模块vue-cli-server build --mode test 确实却打成node环境的。这个表示没有搞明白,后面发现,只有配置了target:'web',就不会打出process.但是webpack的target默认是web,所以估计还是@vue/cli 应该有问题,往下的问题排查已经超出能力范围之外了,所以有心无力。希望某位大佬看到能有更加详细的讲解


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...