嗯都给了注释,要注意的是 css、less、scss 的loader顺序,不要写反因为他是从前往后这样编译的 如果找不到前面的后面的loader也就无法执行 js 的loader用了一段这个
!process.env.NODE_ENV ? 'happypack/loader?id=happy-babel' : 'babel-loader',
因为在生产环境下打包时 js loader的编译会很慢,所以开启了多线程去处理 js loader的编译
HappyPack = require('happypack'), os = require('os'), happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }), //利用多线程解决js loader编译过程耗时 除scss无法使用 css、vue都可使用 (webpack4本来就是多线程) createHappyPlugin = (id, loaders) => new HappyPack({ id: id, loaders: loaders, threadPool: happyThreadPool, verbose: true, //允许 HappyPack 输出日志 });
需要在 plugins 下加上下面这段
createHappyPlugin('happy-babel', [{ loader: 'babel-loader', options: { babelrc: true, cacheDirectory: true // 启用缓存 } }]),
happy-babel 就是找到上面loader的id,但因为webpack4本来就是多线程的,这样做可能多此一举,暂时没有测试过量大时编译效果
还有这个
new VueLoaderPlugin()
在 vue-loader 版本为15.0以后都要加上
其它在升级到webpack4.0后还是有不少的坑,
就比如4之前可用的合并加载文件
new webpack.optimize.MinChunkSizePlugin({minChunkSize: 30000}),
这个已经整合到 splitChunks 里面去了,再用的话就会冲突报错
因为之前没有留意 用3升4的过程中没有删除它,所以大家要重新配置4的时候还是重新一步步配置,否则很多报错都莫名其妙,接着往下看
if (!process.env.NODE_ENV) { for (let i = 1; i < 3; i++) { //使用mini-css-extract-plugin在生产环境要把style-loader覆盖,它们会有冲突 config.module.rules[i].use[0] = { loader: MiniCssExtractPlugin.loader, }; //自动添加样式补全放 config.module.rules[i].use.splice(2, 0, 'postcss-loader'); } //css样式合并 config.plugins.push( new MiniCssExtractPlugin({ filename: utils.assetsPath('css/[name].[chunkhash:8].css'), }) ) }
在 生产环境 下原来是用 ExtractTextPlugin 插件现在都改成了 MiniCssExtractPlugin
for循环里面主要是把 vue、css、less、scss 的第一个数组 style-loader 覆盖成 MiniCssExtractPlugin 否则会有冲突,
自动添加前缀的 postcss-loader 要放到最后面,这也是执行顺序的问题
在项目最外层要增加一个 postcss.config.js 内容是
module.exports = { plugins: [ require('autoprefixer')({ browsers: ['last 20 versions'] }) ] }
require的是一个自动补全css前缀的插件 last 20 versions 指的是兼容主流浏览器最近的20个版本,当然如果想要兼容到某个浏览器的特定版本也可以这样写
'last 10 Chrome versions', 'last 5 Firefox versions', 'Safari >= 6', 'ie> 8
接下来是前面提过的 px转rem 和 eslint 语法检查,是否开启和关闭是在 config.js 里设置
build.js 是这里生产打包,操作都是先清空原来的输出目录,复制静态文件到输出目录 然后打包
const spinner = ora("开始构建生产环境....."); spinner.start(); //清空输出目录 rm("-rf", config.build.outputPath); //复制static到输出目录 utils.copyDir("./static/*", config.build.resourcesPath); webpack(webpackConfig).run((err, stats) => { spinner.stop(); if (err) throw err; // 输出编译结果 process.stdout.write(stats.toString({ colors: true, modules: false, children: false, chunks: false, chunkModules: false, timings: false }) + "\n\n"); });
以上就是使用单页或多页共同的代码块
webpack4 单页配置(single)
单页应用的目录结构主要是这样的,和一般开发中的 vue 项目结构一样
build --views --index.html --404.html --build.js --config.js --dev-server.js --utils.js --webpack.base.conf.js --webpack.dev.conf.js --webpack.prod.conf.js src --conponents --css --font --images --mixins --pages //页面目录 --router --store --App.vue --index.js static --jquery mode_modules
看build里的配置文件,前面讲过了 build.js、config.js、utils.js、webpack.prod.conf.js 现在就先说下 webpack.dev.conf.js
const webpackConfig = merge(baseWebpackConfig, { mode: "development", entry: ["webpack-hot-middleware/client?noInfo=true&reload=true"].concat("./src/index.js"), devtool: "eval-source-map", output: { path: config.build.outputPath, filename: "https://www.jb51.net/index.js", }, module: { rules: [] }, resolve: {}, plugins: [ new webpack.HotModuleReplacementPlugin(), new Jarvis({ port: 1337 }) ], devServer: { inline: true }, });
webpack4.0新增了一个 mode为development/production ,两种模式在不同环境下都做了优化操作,想要访问这两种模式还是需要用到
process.env.NODE_ENV
关于页面热加载直接使用webpack自带的热加载功能 HotModuleReplacementPlugin 然后和入口文件 src/index.js 做一个合并
["webpack-hot-middleware/client?noInfo=true&reload=true"].concat("./src/index.js")
后面的 noinfo 和 reload 是可配置的,如果想继续增加参数可往这里添加, 传送门
然后开启热加载 devServer: { inline: true }
在 output 里的path路径我指向的是打包输出路径,webpack开发环境 是打包到内存的并不是真的打包,filename是给了个固定的 index.js
这个是要写到 html 里做为整个项目的入口,也就是说整个项目运行就靠这个 index.js ,