前言

博主最近在看《Vue.js实战》(梁灏著,2017年10月01日出版),学习vue框架和webpack编译打包。在进行npm run build编译生产环境包时,出现了很多报错,特此记录采坑和解决方案

一. 问题背景

书中首先创建webpack.prod.config.js文件,如下

var webpack = require('webpack');
var HtmlwebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var merge = require('webpack-merge');
var webpackBaseConfig = require('./webpack.config.js');

// 清空基本配置的插件列表
webpackBaseConfig.plugins = [];

module.exports = merge(webpackBaseConfig, {
    output: {
        publicPath: '/dist/',
        //将入口文件重命名为带有20 位 hash 值的唯一文件
        filename: '[name].[hash].js'
    },
    plugins: [
        new ExtractTextPlugin({
            // 提取 css,并重命名为带有20 位 hash 值的唯一文件
            filename: '[name].[hash].css',
            allChunks: true
        }),
        // 定义当前 node 环境为生产环境
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        }),
        // 压缩 js
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        // 提取模板,并保存入口 html文件
        new HtmlWebpackPlugin({
            filename: '../index_prod.html',
            template: './index.ejs',
            inject: false
        })
    ]
});

然后在package.json中添加:

"scripts": {
  "build": "webpack --progress --hide-modules --config webpack.prod.config.js"
}

在执行npm run build时,出现如下错误

二. 问题及解决方案

1. webpack.optimize.UglifyJsPlugin is not a constructor

问题原因:
对于webpack5.27版本,内置的JS压缩插件不能使用了

解决方案:

可以安装uglifyjs-webpack-plugin插件,首先用npm install --save-dev安装,然后在webpack.prod.config.js文件中添加optimization,如下

    ,plugins: [
        // 定义当前 node 环境为生产环境
		.......
        // 提取模板,并保存入口 html文件
        new HtmlwebpackPlugin({
            ......
        })
    ]
    //添加到此处
    ,optimization: {
        minimizer: [
          new UglifyJsPlugin({
            uglifyOptions: {
              compress: false,
            }
          })
        ]
    }
2. TypeError: merge is not a function

问题原因:
查看webpack-merge源码,如下:
在这里插入图片描述
可见最后export 了很多输出项,merge是其中一个方法。而原文中引用的方式不对var merge = require('webpack-merge');这种写法相当于把上面所有输出项组成的object赋值给了merge对象,因此会提示说 TypeError: merge is not a function,merge不是一个函数

解决方案:
精确引用webpack-merge输出的function merge()方法,有两种改法:

  1. 在引入时,写为var {merge} = require('webpack-merge');此时merge为方法
  2. 引入时不变,还为var merge = require('webpack-merge');;在调用时,改为module.exports = merge.merge(webpackBaseConfig, {})
3ReferenceError: HtmlwebpackPlugin is not defined

ERROR in Template execution failed: ReferenceError: HtmlwebpackPlugin is not defined
ERROR in ReferenceError: HtmlwebpackPlugin is not defined

  • index.ejs:11

问题原因:
查看html-webpack-plugin源码,如下
在这里插入图片描述
可以看到export 的class名称为HtmlWebpackPlugin,其中W为大写,并没有用export default输出未命名变量,因此名称得精确匹配。而原文中为HtmlwebpackPlugin,w为小写

解决方案:
改为
var HtmlWebpackPlugin = require('html-webpack-plugin');

同时index.ejs中也得将htmlWebpackPlugin的w改为大写

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>webpack App</title>
    <link rel="stylesheet" href="<%= htmlWebpackPlugin.files.css[0] %>">
</head>
<body>
    <div id="app"></div>
    <script type="text/javascript" src="<%= htmlWebpackPlugin.files.js[0] %>"> </script>
</body>
</html> 
4. You may need an additional loader to handle the result of these loaders.

npm run build编译时,报错如下:

Module parse failed: Unexpected token (2:0) File was processed with
these loaders: * ./node_modules/vue-loader/lib/index.js You may need
an additional loader to handle the result of these loaders. |
ERROR in ./vuefile/app2.vue

问题原因:
以上报错有四处之多;在npm run dev时,没有报错,程序成功启动,服务可访问。因此判断:build时loader没加载成功,merge并没有将webpack.config.js中的plugins:[]引入到build中

解决方案:
webpack.config.js之前写好的plugins的几个loader加入webpack.prod.config.js中,包括VueLoaderPluginMiniCssExtractPlugin

最终webpack.prod.config.js代码如下

var webpack = require('webpack');

var {merge} = require('webpack-merge');
var webpackBaseConfig = require('./webpack.config.js');

var HtmlWebpackPlugin  = require('html-webpack-plugin');
var UglifyJsPlugin=require('uglifyjs-webpack-plugin');
var { type } = require('os');

const VueLoaderPlugin = require('vue-loader/lib/plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');


// 清空基本配置的插件列表
webpackBaseConfig.plugins = [];

// prod配置是在webpack.config.js基础上扩展的
module.exports = merge(webpackBaseConfig, {

    output: {
    	publicPath: '/dist/',
        //将入口文件重命名为带有20 位 hash 值的唯一文件
        filename: '[name].[hash].js'
    }
    ,plugins: [
        // 引入VueLoader插件
        new VueLoaderPlugin(),

        // // 重命名提取后的css文件
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename: "[id].css"
        }),
        // 定义当前 node 环境为生产环境
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        }),
        // 提取模板,并保存入口 html文件
        new HtmlWebpackPlugin({
            filename: './index_prod.html',
            template: './prod/index.ejs',
            inject: false
        })
    ]
    ,optimization: {
        minimizer: [
          new UglifyJsPlugin({
            uglifyOptions: {
              compress: false,
            }
          })
        ]
    }
})

Logo

前往低代码交流专区

更多推荐