const merge = require('webpack-merge'); const base = require('./webpack.base'); module.exports = merge({ mode: 'production', output: { filename: 'js/[name]_[contenthash].js', // 入口和内容hash组成的文件名,也可以是hash chunkFilename: 'js/[name]_[contenthash].chunk.js' } }, base)
然后在package.json里添加执行脚本:
"scripts": { "build": "webpack --config ./build/webpack.prod.js" }
webpack默认会找名为webpack.config.js的文件,由于我们将其拆解为prod和dev,所以我们要手动指定webpack执行的文件,添加--config,即可手动指定目录。下面我们开始写一段代码试试吧,在index.js中写入如下es6代码:
// index.js let name = 'xuxi'; let say = (name) => { alert(name) }; say(name);
下面我们执行:
npm run build
此时我们会看见项目中多了一个dist目录,里面的html也植入了相应的代码,
在浏览器中打开:
ok,第一步完成。 下一步是支持css,我们先安装如下几个模块:
npm install --save-dev css-loader style-loader
在webpack.base.js中的module中添加如下代码:
module: { rules: [ // 将es6编译成es5 { test: /\.jsx?$/, // ?表示x有0个或一个 exclude: /node_modules/, // 不编译某个目录下的文件 include: path.resolve(__dirname, '../src'), // 只在include包含的目录下进行loader编译 use: [ "babel-loader", ] }, // 加载css { test: /\.css$/, use: ['style-loader', 'css-loader'], }, ] }
注意,laoder的加载顺序是从下往上,从右往左的,所以配置loader的时候要注意一下顺序。 此时在styles目录下加入app.css,在js中引入:
// app.css #root { background-color: #f0c; height: 100px; } // index.js import './styles/app.css'
此时打开浏览器,可以看到css生效了:
现在css导入虽然生效了,但是是有js动态创建添加到head里面的,如果后期项目复杂了,将会严重影响项目的加载速度,所以我们这里需要另一个插件,对css进行代码分割,单独生成css文件:
npm isntall mini-css-extract-plugin -D
根据该插件的官方配置,我们需要把style-loader替换成该插件提供的loader,并配置导出的css文件目录和文件名,为了提高开发环境构建速度,我们只在生产环境分割css:
// webpack.prod.js const merge = require('webpack-merge'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const base = require('./webpack.base'); module.exports = merge({ mode: 'production', output: { filename: 'js/[name]_[contenthash].js', // 入口和内容hash组成的文件名,也可以是hash chunkFilename: 'js/[name]_[contenthash].chunk.js' }, module: { rules: [ { test: /\.css$/, use: [ // loader解析的顺序是从下到上,从右到左的顺序 { loader: MiniCssExtractPlugin.loader, options: { filename: '[name].css', chunkFilename: '[name].css', publicPath: '../' //****最后打包的时候替换引入文件路径 }, }, // 'style-loader', 使用MiniCssExtractPlugin时就不能使用style-loader了 { loader: 'css-loader', options: { importLoaders: 2 //该方式可以让@import引入的css文件再次执行一边css打包loader } }, ] } ] }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: 'css/[name]_[hash].css', chunkFilename: 'css/[name]_[hash].chunk.css', }), ] }, base)
由于我们在dev和prod环境的css-loader不一样,所以我们将base的css-loader配置删除,移到dev下
// webpack.dev.js const base = require('./webpack.base'); const merge = require('webpack-merge'); const webpack = require('webpack'); module.exports = merge({ mode: 'development', module: { rules: [ { test: /\.css$/, use: [ // loader解析的顺序是从下到上,从右到左的顺序 'style-loader', //使用MiniCssExtractPlugin时就不能使用style-loader了 { loader: 'css-loader', options: { importLoaders: 2 //该方式可以让@import引入的css文件再次执行一边css打包loader } }, ] } ] }, output: { filename: '[name].js', chunkFilename: '[name].js', } }, base)
ok,此时我们就完成一个基本的打包es6,css的模块打包工具,为了支持更高的es6+语法,我们配置.babelrc文件,以及安装相应的npm包:
npm install @babel/polyfill core-js -D
.babelrc文件如下:
{ "presets": [ [ "@babel/preset-env", // 将ES6语法转换为es5 { "useBuiltIns": "usage", // 只编译需要编译的代码 "corejs": "3.0.1", } ], ] }
我们会看到babelrc文件里面有"useBuiltIns": "usage", 这个配置涉及到一个关于webpack打包的高级用法,tree-shaking。