webpack3到4的迁移

webpack4大幅度减少配置成本。为了优化打包流程和打包效率,决定升级新版本,拥抱新技术

计划步骤:

  1. 从现有的一个项目,找到每个配置的作用是什么,以及新旧版本的区别,然后制定修改方案,同时埋好日志输出,便于排查错误
  2. 打包测试,修正问题

找到每个配置的作用是什么,以及新旧版本的区别,然后制定修改方案,同时埋好日志输出,便于排查错误

为防止不同npm包版本兼容有问题,我们把所有涉及到的包都升级到最新

先把"webpack": "3.6.0",升级到4.39.3

打开项目根目录下package.jsonscripts下的dev开始分析

webpack-dev-server --config build/webpack.dev.conf.js // 通过webpack-dev-server启动的本地服务。看到最新版本webpack-dev-server,需要webpack4,索性把webpack-dev-server升级到最新版,把原来的 "webpack-dev-server": "2.9.1", 改成 "3.8.0" 

分析build/webpack.dev.conf.js文件

引入的插件

const merge = require('webpack-merge') // "webpack-merge": "4.1.0" 升级到 "4.2.2"
const HtmlWebpackPlugin = require('html-webpack-plugin') // "html-webpack-plugin": "2.30.1" 升级到 "3.2.0"
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') // 最新版不用动
const portfinder = require('portfinder') // "portfinder": "1.0.13" 升级 "1.0.23"

引入其他文件const utils = require('./utils')

webpack4,ExtractTextPlugin废弃了,需要换成MiniCssExtractPlugin

const ExtractTextPlugin = require('extract-text-webpack-plugin') // 用于提取css文件 webpack4 不需要用这个插件, 换成 mini-css-extract-plugin
// 在工程里搜索 extract-text-webpack-plugin 发现可能有用到的文件或者包有:
1. /build/utils.js
// const ExtractTextPlugin = require('extract-text-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
if (options.extract) {
      // return ExtractTextPlugin.extract({
      //   use: loaders,
      //   fallback: 'vue-style-loader'
      // })
      return [
        {
          loader: MiniCssExtractPlugin.loader
        },
        'css-loader'
      ] 
 } 
2. /build/webpack.prod.conf.js
// new ExtractTextPlugin({
new MiniCssExtractPlugin({
3. 包 avg // 未在package.json中出现,不做处理
4. 包 async // 未在package.json中出现,不做处理
5. 包 css-loader // "css-loader": "0.28.0", 升级到 "3.2.0"
6. 包 element-ui // "element-ui": "2.3.2", 升级到2.11.1
7. 包 html-webpack-plugin // 已经升级过
8. 包 loader-utils // 未在package.json中出现,不做处理
9. 包 optimize-css-assets-webpack-plugin // "3.2.0",升级到5.0.3
10. 包 postcss-loader // "postcss-loader": "2.0.8", 升级到3.0.0
11. 包 sass-loader // 6.0.6,升级到7.3.1
12. 包 schema-utils // 未在package.json中出现,不做处理
13. 包 svg-sprite-loader // 3.7.3 升级到4.1.6
14. 包 tabel // 未在package.json中出现,不做处理 
15. 包 ajv // 未在package.json中出现,不做处理 
16. 包 ve-calendar // 没有新版本暂时不处理
17. 包 vue-loader // 13.3.0 升级到15.7.1
18. 包 vue-resize-directive // 未在package.json中出现,不做处理 
19. 包 webpack-sources // 未在package.json中出现,不做处理 

引入其他文件const config = require('../config')

根据不同环境:develop或者production等采取不同的配置,可能一些配置和webpack4不一致,暂定不需修改。

引入其他文件const baseWebpackConfig = require('./webpack.base.conf')

引入文件 vue-loader.conf,用于vue-loader需要的配置,暂定不需修改。

分析build/webpack.dev.conf.js文件配置的参数

暂定不需修改

打包测试,修正问题

安装npm包

删掉node_modules目录

执行npm i

npm WARN element-ui@2.11.1 requires a peer of vue@^2.5.17 but none is installed. You must install peer dependencies yourself.

提示element-ui需要vue@2.5.17,将vue升级到2.6.10。重新npm i

npm WARN babel-loader@7.1.1 requires a peer of webpack@2 || 3 but none is installed. You must install peer dependencies yourself.
npm WARN file-loader@1.1.4 requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN uglifyjs-webpack-plugin@1.1.1 requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.

升级babel-loader到8.0.6,升级file-loader到4.2.0,webpack4.0已经不用uglifyjs-webpack-plugin,直接删掉。重新npm i

npm WARN babel-loader@8.0.6 requires a peer of @babel/core@^7.0.0 but none is installed. You must install peer dependencies yourself.

升级babel-core@babel/core] 7.5.5重新npm i

测试

npm run dev

The CLI moved into a separate package: webpack-cli
Please install 'webpack-cli' in addition to webpack itself to use the CLI
# 安装webpack-cli 
npm install webpack-cli --save-dev

重新npm run dev

ERROR  Failed to compile with 1 errors                             
Module build failed (from ./node_modules/eslint-loader/index.js):
TypeError: Cannot read property 'eslint' of undefined at Object.module.exports (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint-loader/index.js:155:18)

eslint-loader 1.7.1升级到3.0.0, 重新npm i

npm WARN eslint-loader@3.0.0 requires a peer of eslint@^5.0.0 || ^6.0.0 but none is installed. You must install peer dependencies yourself.

eslint 3.19.0升级到6.2.2, 重新npm i

npm WARN eslint-plugin-import@2.7.0 requires a peer of eslint@2.x - 4.x but none is installed. You must install peer dependencies yourself.
npm WARN acorn-jsx@5.0.2 requires a peer of acorn@^6.0.0 || ^7.0.0 but none is installed. You must install peer dependencies yourself.

eslint-plugin-import 2.7.0升级到2.18.2。

通过命令npm ls查看整个包依赖树,

webpack-bundle-analyzer 引用了acorn@5.7.3,所以把webpack-bundle-analyzer2.9.0升级到3.4.1

另外一个引用jest@21.2.0 -> jest-cli -> jest-environment-jsdom -> jsdom -> acorn@4.0.13 所有把jest@21.2.0升级到24.9.0

重新npm i

还是有警告

npm WARN acorn-jsx@5.0.2 requires a peer of acorn@^6.0.0 || ^7.0.0 but none is installed. You must install peer dependencies yourself.

依赖树中看到

│ │ ├── UNMET PEER DEPENDENCY acorn@7.0.0
│ │ ├── acorn-jsx@5.0.2

只好手动安装acorn最新版本

npm install acorn --save-dev

重新npm i

没有警告

npm run dev

Module build failed (from ./node_modules/eslint-loader/dist/cjs.js):
TypeError: Cannot read property 'forEach' of undefined
    at Linter.parseResults (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint-loader/dist/Linter.js:121:13)
    at Linter.printOutput (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint-loader/dist/Linter.js:85:26)
    at Object.loader (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint-loader/dist/index.js:26:10)

表面上看不出这个错误导致是怎么导致的。在/node_modules/eslint-loader/dist/Linter.js的lint(content)函数中输出捕获的错误.

Failed to load plugin 'html' declared in '.eslintrc.js': eslint-plugin-html error: It seems that eslint is not loaded. If you think it is a bug, please file a report at https://github.com/BenoitZugmeyer/eslint-plugin-html/issues
    at iterateESLintModules (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint-plugin-html/src/index.js:79:11)
    at Object.<anonymous> (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint-plugin-html/src/index.js:21:1)
    at Module._compile (internal/modules/cjs/loader.js:738:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:749:10)
    at Module.load (internal/modules/cjs/loader.js:630:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:570:12)
    at Function.Module._load (internal/modules/cjs/loader.js:562:3)
    at Module.require (internal/modules/cjs/loader.js:667:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at ConfigArrayFactory._loadPlugin (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint/lib/cli-engine/config-array-factory.js:861:49)

eslint-plugin-html从3.0.0升级到6.0.0

npm i

成功升级eslint-plugin-html

npm run dev

 Cannot find module 'escope'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:613:15)
    at monkeypatch (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/babel-eslint/index.js:53:26)
    at Object.exports.parse (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/babel-eslint/index.js:358:5)
    at parse (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint/lib/linter/linter.js:625:29)
    at Linter._verifyWithoutProcessors (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint/lib/linter/linter.js:1067:33)
    at Linter.(anonymous function) (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint-plugin-html/src/index.js:151:21)
    at Linter._verifyWithConfigArray (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint/lib/linter/linter.js:1210:21)
    at Linter.verify (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint/lib/linter/linter.js:1165:25)
    at Linter.verifyAndFix (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint/lib/linter/linter.js:1355:29)
    at verifyText (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/eslint/lib/cli-engine/cli-engine.js:231:48)

babel-eslint版本也比较老,7.1.1换成 10.0.3

npm i

成功升级babel-eslint

npm run dev

Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: .plugins[1][1] must be an object, false, or undefined
    at assertPluginItem (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/validation/option-assertions.js:244:15)
    at arr.forEach (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/validation/option-assertions.js:222:30)
    at Array.forEach (<anonymous>)
    at assertPluginList (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/validation/option-assertions.js:222:9)
    at Object.keys.forEach.key (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/validation/options.js:107:5)
    at Array.forEach (<anonymous>)
    at validateNested (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/validation/options.js:83:21)
    at validate (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/validation/options.js:74:10)
    at file (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/config-chain.js:174:34)
    at cachedFunction (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/caching.js:33:19)

/node_modules/@babel/core/lib/config/validation/options.js添加日志输出

console.log('optLoc--------', optLoc)
console.log('opts--------', opts)
console.log('key-----', key)
    validator(optLoc, opts[key]);
// 报错的前的输出是
optLoc-------- { type: 'option',
  name: 'plugins',
  parent: { type: 'root', source: 'babelrcfile' } }
opts-------- { presets: [ [ 'env', [Object] ], 'stage-2' ],
  plugins: [ 'transform-runtime', [ 'component', [Array] ] ],
  env: { test: { presets: [Array], plugins: [Array] } } }
key----- plugins
// 是babelr配置文件出问题了,这里应该是babel修改配置规则了,plugins里的元素不能是数组了

修改.babelrc文件

"plugins": ["transform-runtime", ["component", [
  {
    "libraryName": "element-ui"
  }
]]]
改为    
"plugins": ["transform-runtime", "component": [
  {
    "libraryName": "element-ui"
  }
]]

npm run dev

Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Plugin/Preset files are not allowed to export objects, only functions. In /Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/babel-preset-stage-2/lib/index.js
    at createDescriptor (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/config-descriptors.js:178:11)
    at items.map (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/config-descriptors.js:109:50)
    at Array.map (<anonymous>)
    at createDescriptors (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/config-descriptors.js:109:29)
    at createPresetDescriptors (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/config-descriptors.js:101:10)
    at presets (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/config-descriptors.js:47:19)
    at mergeChainOpts (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/config-chain.js:320:26)
    at /Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/config-chain.js:283:7
    at buildRootChain (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/config-chain.js:120:22)
    at loadPrivatePartialConfig (/Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/@babel/core/lib/config/partial.js:85:55)

先将babel-preset-stage-2从6.22.0升级到6.24.1

npm i

成功升级babel-preset-stage-2

npm run dev

一样的错误

/@babel/core/lib/config/config-chain.js283行添加打印日志

console.log('chain--',  chain)
console.log('op--',  op)
      mergeChainOpts(chain, op);
// 报错前输出
chain-- { options: [], presets: [], plugins: [] }
op-- { options:
   { presets: [ [Array], 'stage-2' ],
     plugins: [ 'transform-runtime', [Object] ],
     env: { test: [Object] } },
  plugins: [Function: plugins],
  presets: [Function: presets] }

babel-plugin-transform-runtime@6.22.0更新为@babel/plugin-transform-runtime@7.5.5

.babelrc文件中

"plugins": ["transform-runtime", {
 改为
"plugins": ["@babel/plugin-transform-runtime", {

npm i

这里一直报babel的错,把babel的相关包都做下升级

"babel-plugin-dynamic-import-node": "1.2.0", => 2.3.0
"babel-plugin-transform-es2015-modules-commonjs": "6.26.0", => 6.26.2
"babel-preset-env": "1.3.2", => 1.7.0
"babel-register": "6.22.0", => 6.26.0
"babel-plugin-component": "0.10.1", => 1.1.1

npm i

npm run dev 一样的错,在网上找到有将babel-preset-env换成 @babel/preset-env,试下

"babel-preset-env": "1.7.0", => "@babel/preset-env" : "7.5.5",
"babel-register": "6.26.0",  => "@babel/register" : "7.5.5", // 一起改掉
"babel-polyfill": "6.26.0", => "@babel/polyfill" : "7.4.4", // 一起改掉

npm i

npm run dev 依然报错

临时把.babelrc文件简化

{
   "presets": ["@babel/preset-env"]
}

npm run dev

报其他错误。

先做下相关npm包升级

"vue-template-compiler": "2.5.2", => "2.6.10",
"vue-style-loader": "3.0.1",  => "@babel/register" : "4.1.2", 

依然报错

有个老兄说 webpack4 不兼容vue-loader 15.x.x版本https://www.cnblogs.com/tugenhua0707/p/9695179.html

我也把vue-loader 降低成^14.2.2

之前错误没了,只有eslint的错误

暂时将/config/index.js中的useEslint设置成false,

npm run dev

终于跑起来了

/config/index.js中的useEslint设置成true

eslint相关的包升级为最新

"eslint-config-standard": "10.2.1", => "14.1.0",
"eslint-friendly-formatter": "3.0.0",  => "4.0.1", 
"eslint-plugin-node": "5.2.0", => "10.0.0",
"eslint-plugin-promise": "3.5.0",  => "4.2.1", 
"eslint-plugin-standard": "3.0.1",  => "4.0.1", 

npm i

npm run dev 依然报错,猜测可能和简化.babelrc有关系

把babelrc中的配置一点点加回来

{
   "presets": [["@babel/preset-env", {"modules": false}], "stage-2"]
}

npm run dev 依然报错

查到babel7 stage-2的文章 https://babeljs.io/docs/en/babel-preset-stage-2 发现babel-preset-stage-2插件需要更换

"babel-preset-stage-2": "6.24.1",  => "@babel/preset-stage-2": "7.0.0", 

npm i

babelrc中的配置修改

{
   "presets": [["@babel/preset-env", {"modules": false}], "@babel/preset-stage-2"]
}

npm run dev , 提示As of v7.0.0-beta.55, we've removed Babel's Stage presets.发现babel7已经移除了stage preset https://babeljs.io/blog/2018/07/27/removing-babels-stage-presets

babelrc中去掉@babel/preset-stage-2 并添加pluginx component的结构做了点调整

{
  "presets": [["@babel/preset-env", {"modules": false}]],
  "plugins": [
    "@babel/plugin-transform-runtime", 
    [ 
      "component",
      {
        "libraryName": "element-ui"
      }
    ]
  ]
}

npm run dev

# 提示错误信息
These dependencies were not found:
* @babel/runtime/helpers/defineProperty in ./src/router/index.js
...

添加@babel/runtime

"@babel/runtime": "^7.6.0"

npm i

npm run dev

# 提示错误信息
These dependencies were not found:
* element-ui/lib/alert/style.css in ./src/element-ui/index.js
* element-ui/lib/aside/style.css in ./src/element-ui/index.js
...

element包导入有问题,babelrc需要添加styleLibraryName用来加载样式文件

{
  "presets": [["@babel/preset-env", {"modules": false}]],
  "plugins": [
    "@babel/plugin-transform-runtime",
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

npm run lint(lint配置在package中)

还是报错

http://eslint.org/docs/rules/dot-notation  ["children"] is better written in dot notation  
  src/utils/index.js:36:31
...
    1 | <template>
  2 |   <div class="mod-user">
> 3 |     <el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
    |                     ^
  4 |       <el-form-item>
  5 |         <el-input v-model="dataForm.userName" placeholder="用户名" clearable></el-input>
  6 |       </el-form-item>

首先先 将 --fix 添加到package中的lint脚步中

"scripts": {
  ...
  "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs --fix",
    ...
},

npm run lint

只剩下vue lint 相关的错误

看到.eslintrc.js中,plugins:[ 'html'] 上有注释// required to lint *.vue files 查了下eslint-plugin-html插件

发现

Linting VUE files
Initially, eslint-plugin-vue was using eslint-plugin-html to lint code inside script tags. Since v3, eslint-plugin-vue is using its own parser, so it is incompatible with eslint-plugin-html. You should use eslint-plugin-vue exclusively and remove eslint-plugin-html from your dependencies if you still have it.

原来用 eslint-plugin-html插件就可以检测vue文件,现在更换最新的eslint-plging-vue

// 删除
"eslint-plugin-html"
// 添加
"eslint-plugin-vue": "^5.2.3",

参考https://vuejs.github.io/eslint-plugin-vue/user-guide/#faq

.eslintrc.js修改plugin

  "plugins": [
    "vue",
-   "html"
  ]

.eslintrc.js修改extends

  extends: ['plugin:vue/essential', 'standard'],

.eslintrc.js修改parserOptions 添加 parser: 'babel-eslint' 这个是为了给eslint-plugin-vue提供解析 .vue文件中<script>标签中的代码,因为eslint-plugin-vue的解析器只解析<template>标签里的内容

去掉原来的parser

- "parser": "babel-eslint",
  parserOptions: {
    sourceType: 'module',
      parser: 'babel-eslint',
  },

npm run lint

仅剩下一些defined but never used的错误,逐个更正

npm run lint 成功

.babelrc中添加完剩下的信息

之前的evn配置

"env": {
  "test": {
    "presets": ["env", "stage-2"],
      "plugins": ["transform-es2015-modules-commonjs", "dynamic-import-node"]
  }
}

但是并没有地方使用。

babel会 从按这个顺序找到一个环境变量值process.env.BABEL_ENV || process.env.NODE_ENV || "development"

然后用这个值做为key,在上面的env配置中找到信息,合并到根对象中指定的选项之上。

但是项目中并没有设置 process.env.BABEL_ENV || process.env.NODE_ENV 的地方,所以不会解析test里的内容,除非程序运行所在电脑上配置BABEL_ENV 环境变量为test

如果改成新版的形式: 因为不需要指定 stage的preset 所以去掉preset。 plugins里的 transform-es2015-modules-commonjs 改成 @babel/plugin-transform-modules-commonjs,dynamic-import-node不需要改。但是暂时不用test这些,整个env配置都先去掉,后面要在test环境测试一些插件,再添加上。

开发环境修改完毕,测试下生产环境

npm run build

Error: Cannot find module 'del'

在package.lock文件中搜索这个模块,发现是webpack-dev-server的依赖,删除package.lock从新安装webpack-dev-server

npm run build

Error: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.

按官方文档添加splitChunks

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      automaticNameMaxLength: 30,
      name: true,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
};

npm run build

.scss文件中一些sass的写法,报错

比如 双斜线注释// 会报错 需改成 /* */ ; @import 下划线开头的scss文件,需要严格写文件名包括后缀,否则报错

npm run build

报错

⠧ building for production.../Users/treePro/develop/X/good_things/common-manage-platform-vue/node_modules/copy-webpack-plugin/dist/index.js:127
                    compilation.contextDependencies.push(context);
                                                    ^

TypeError: compilation.contextDependencies.push is not a function

更新copy-webpack-plugin

"copy-webpack-plugin": "4.0.1", => "copy-webpack-plugin": "5.0.4",

npm i

npm run build 打包成功

本地启动nginx服务,制定dist目录位置静态服务目录

浏览器访问 http://localhost/index.html 
// 报错
index.js?t=1568122675619:86 GET http://localhost/1909100108/static/js/manifest.js net::ERR_ABORTED 404 (Not Found)

发现 manifest.js 和 vendor.js 没有导出

查了一通

// 去掉 output 里的 chunkFilename: utils.assetsPath('js/[id].js')
// optimization 添加 runtimeChunk
optimization: {
  runtimeChunk: {
      name: "manifest" // 所有生成 chunk 之间共享的运行时文件打包到 manifest
  },  

npm run build 正常h输出manifest.js 和 vendor.js

刷新页面发现样式错乱,调试发现 .vue文件里的scss没有提取出来。猜测是不是mini-css-extract-plugin的问题

发现/build/utils.js 中有问题

return [
  {
    loader: MiniCssExtractPlugin.loader
  },
  'css-loader'
]
// 改成
return [MiniCssExtractPlugin.loader].concat(loaders)

npm run build 刷新页面,正确

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容

  • babel官网 babel 介绍 Babel 是一个通用的多用途 JavaScript 编译器。通过 Babel ...
    锋享前端阅读 1,811评论 0 10
  • webpack-4.x 安装 npm i webpack -g: 全局安装webapck 基本使用 不使用配置文件...
    duans_阅读 1,720评论 0 12
  • 最近学习webpack相关知识,特此记录下学习过的文档以及搭建过程;如有错误,记得告诉我呀。项目地址:地址,求星星...
    前端gogogo阅读 958评论 0 0
  • babel 7 的使用的个人理解 最近看了很多关于babel的使用方法,大部分在一些点上都没有说明白,同时给出的代...
    zshawk1982阅读 20,985评论 14 43
  • 本文主要从一个上线项目的packge.json分析一个上线项目中常见的插件以及为什么会引入这些插件。 通过这些配置...
    Leslie_2386阅读 985评论 0 2