1. Introduction

Thanks to the Parcel packaging tool, WebPack4 is also pursuing zero-configuration build projects. Vue-cli 3.0, which appeared a while ago, is also based on the idea of webpack4 zero configuration. For some used to Webpack3 developers inevitably some not used to. This article will take you around vuE-CLI, with Webpack4 step by step build vUE project. Note: This article describes the basic configuration of Webpack4. It is a bit long, please read it patiently. Or view the project source directly, or CTRL + W)Copy the code

2. Project construction

Create the createVue folder, go to that folder, and NPM init initializes the project to install the webPackCopy the code
NPM I webpack webpack-cli webpack-dev-server webpack-merge --save-dev // The current version I use"webpack": "^ 4.16.3"."webpack-cli": "^ 3.1.0"."webpack-dev-server": "^ 3.1.5." ", // Development server"webpack-merge": "^ 4.1.4." "// WebPack configuration mergeCopy the code
Create file createVue | - dist | - build | -- webpack. Prod. Js | -- webpack. Dev. Js | -- webpack. Base. Js | - SRC | -- index. Js | -- app. Vue |--index.htmlCopy the code
Const webpack = require(// webpack.base.js // dev/prod /'webpack');

module.exports = {
  entry: './src/index.js'Rules: []}, plugins: [//hashChange every time new webpack. HashedModuleIdsPlugin (),, / / plug-in};Copy the code
// webpack.dev.js // dev configuration const merge = require('webpack-merge');
const common = require('./webpack.base.js');
const path = require('path');

module.exports = merge(common, {
  devtool: 'inline-source-map', devServer: {// development server contentBase:'.. /dist'}, output: {// filename:'js/[name].[hash].js'// Save each timehashPath: path.resolve(__dirname,'.. /dist')
  },
  module: {},
  mode: 'development'});Copy the code
// webpack.prod.js // store prod configuration const path = require('path'); // merge configuration files const merge = require('webpack-merge');
const common = require('./webpack.base.js');

module.exports = merge(common, {
  module: {},
  plugins: [],
  mode: 'production',
  output: {
    filename: 'js/[name].[contenthash].js'Resolve (__dirname, //contenthash)'.. /dist')}});Copy the code
Webpack4 added the mode attribute, set to development/production. The default configuration development is as follows: Set the value of process.env.node_env to development to enable the following plug-ins by default, making full use of persistent caching. NamedChunksPlugin: Solidify chunk ID by name NamedModulesPlugin: Solidify Module ID production by name: Setting the value of process.env.node_env to production enables the following plug-ins by default, Including SideEffectsFlagPlugin and UglifyJsPlugin for tree - shaking FlagDependencyUsagePlugin: compile time depends on tag FlagIncludedChunksPlugin: Markup chunks, prevent child chunks loaded ModuleConcatenationPlugin: NoEmitOnErrorsPlugin: Scope hosting (scope hosting) : Scope hosting (scope hosting) : Scope hosting (scope hosting) During the output phase, a compilation error is encountered skipping OccurrenceOrderPlugin: give the shorter value SideEffectsFlagPlugin to the frequently used IDS: Recognize the sideEffects flag of package.json or module.rules (pure ES2015 module) and safely remove unused export export UglifyJsPlugin: Remove unreferenced code and compress itCopy the code
// index.js // NPM I vue --save import vue from'vue';
import App from './App.vue'
import './index.scss'
new Vue({
  el: '#app',
  render: h => h(App),
});
Copy the code
<! -- app.vue --> <template> <div id="app">
    hello world
  </div>
</template>

<script>
export default {
  name: 'app'
}
</script>

<style scoped>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  transform: rotate(0deg);
}
</style>
Copy the code
<! -- index.html --> <! DOCTYPE html> <html> <head> <meta charset="UTF-8">
    <title>Suporka Vue App</title>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
Copy the code
Install vUE core parser NPM I vue-loader vue-template-compiler --save-dev //"vue-loader": "^ 15.2.6"."vue-template-compiler": "^ 2.5.17"Base // webpack.base.js //... // VueLoaderPlugin const VueLoaderPlugin = require('vue-loader/lib/plugin'); module.exports = { //... Ellipsis module: {rules: [{test: /\.vue$/,
        loader: 'vue-loader'}]}, plugins: [// please make sure to introduce this plugin to cast magic new VueLoaderPlugin(),]};Copy the code
Install NPM I html-webpack-plugin --save-dev //"html-webpack-plugin": "^ 3.2.0"HTML parsing is also a basic configuration, grouped under base // webpack.base.js //... // HTML plugin const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { //... New HtmlWebpackPlugin({template: path.resolve(__dirname,'.. /index.html'),})]};Copy the code
Create the NPM command"scripts": {
  "start": "webpack-dev-server --hot --open --config build/webpack.dev.js"."build": "webpack --config build/webpack.prod.js"}, - Hot module hot replacement - open Start the local server at this time, the project can run normallyCopy the code

3. Function expansion

Adding loader CSS Loader (including pre - and post-processing) Basic CSS Loader"css-loader": "^ 1.0.0"."style-loader": "^ 0.21.0"The CSS processes the less two sets"less": "^ 3.8.0." "."less-loader": "^ 4.1.0." ", the CSS has two sets of sASS"node-sass": "^ 4.9.2." "."sass-loader": "^ 7.1.0"CSS Postprocessing PostCSS consists of two parts"postcss-loader": "^ 2.1.6"."autoprefixer": "^ 9.1.0"// postcss.config.js // automatically add CSS compatibility property module.exports = {plugins: [require()'autoprefixer')]}Copy the code
// webpack.base.js //... Ellipsis rules: [{test: /\.(sa|sc|c)ss$/,
    use: [
      'style-loader'.'css-loader'.'postcss-loader'.'sass-loader',]}, {test: /\.less$/,
    use: [
      'style-loader'.'css-loader'.'postcss-loader'.'less-loader',]}]Copy the code
NPM I file-loader --save-dev base file // webpack.base.js //... Rules: [//... ellipsis {test: /\.(png|svg|jpg|gif)$/,
    use: [
      {
        loader: 'file-loader',
        options: {
          limit// Separate images to imGS folder name:"imgs/[name].[ext]",}},]},]Copy the code

4. Package optimization

// cleanWebpack-plugin // webpack.prod.js // CleanWebpackPlugin = require('clean-webpack-plugin'); / /... Plugins: [new CleanWebpackPlugin(['dist/*'], {
    root: path.resolve(__dirname, '.. / '}),] Separate CSS Using the mini-CSs-extract-plugin in Webpackage 4. // extract/MiniCssExtractPlugin // extract/MiniCssExtractPlugin = require("mini-css-extract-plugin"); / /... [new MiniCssExtractPlugin({filename:"css/[name].[hash].css",
    chunkFilename: 'css/[id].[hash].css'}),] In addition, it is necessary to replace style-loader in each CSS loader with MiniCssExtractPlugin image compression using image-webpack-loader, the code after installation is as follows:  // webpack.prod.js // ... Ellipsis rules: [{test: /\.(sa|sc|c)ss$/,
    use: [
      {
        loader: MiniCssExtractPlugin.loader,
        options: {
          // you can specify a publicPath here
          // by default it use publicPath in webpackOptions.output
          publicPath: '.. / '}},'css-loader'.'postcss-loader'.'sass-loader',]}, {test: /\.less$/,
    use: [
      {
        loader: MiniCssExtractPlugin.loader,
        options: {
          // you can specify a publicPath here
          // by default it use publicPath in webpackOptions.output
          publicPath: '.. / '}},'css-loader'.'postcss-loader'.'less-loader',]}, {test: /\.(png|svg|jpg|gif)$/,
    use: [
      {
        loader: 'file-loader',
        options: {
          limit: 5000,
          name: "imgs/[hash].[ext]"}}, // image compression {loader:'image-webpack-loader',
        options: {
          //   bypassOnDebug: true,
          mozjpeg: {
            progressive: true,
            quality: 65
          },
          optipng: {
            enabled: false,
          },
          pngquant: {
            quality: '65-90',
            speed: 4
          },
          gifsicle: {
            interlaced: false,}},},]},]Copy the code
Use happypack to speed up compilation and also install Babel"babel-core": "^ 6.26.3"."babel-loader": "^ 7.1.5." "."happypack": "^ 5.0.0"Happypack development production environment is used, configuration belongs to baseCopy the code
// webpack.base.js // use happypack const happypack = require('happypack');
const os = require('os'); const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }); / /... Ellipsis rules: [{test: / \. Js $/, / / to. Js file processing to id for happyBabel HappyPack instance execution loader:'happypack/loader? id=happyBabel'// Exclude: /node_modules/ / exclude: /node_modules/},], plugins: [//... new HappyPack({// use id to identify the HappyPack file id:"happyBabel"Loaders: [{loader:"babel-loader? cacheDirectory=true"}], // share process pool threadPool: happyThreadPool, // allow HappyPack to print log verbose:true}),]Copy the code
Exports = merge(common, {//... {// chunks splitChunks: {chunks:'all',
      cacheGroups: {
        vendor: {
          name: "vendor".test: /[\\/]node_modules[\\/]/,
          priority: 10,
          chunks: "initial"},},},}); // Package only the original dependent third party},}},},}) so configured, the packaged js folder will have an additional vendor.jsCopy the code
Optimize - CSS-assets -webpack-plugin and uglifyjs-webpack-plugin // optimize- CSS-assets -webpack-plugin // Const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); module.exports = merge(common, { // ... Optimization: {//... Minimizer: [// compress JS new UglifyJsPlugin({uglifyOptions: {compress: {warnings:false// Remove warning drop_debugger:true// Remove debugger drop_console:true// Remove console.log},}, cache:true, // enable caching parallel:true// Parallel compressionsourceMap: false // set to true if you want JS sourceMaps}), // Compression CSS new OptimizeCSSAssetsPlugin({})]},})Copy the code
The chunkhash, contenthash, chunkhash, contenthash, chunkhash, contenthash, chunkhash, contenthash, chunkhash, contenthash, chunkhash, contenthash, chunkhash, contenthash, chunkhash, contenthash, chunkhash, contenthash, chunkhash, contenthash, chunkhash, contenthash In addition, all files share the same hash value. Unlike hash, chunkhash parses dependent files based on different Entry files, constructs corresponding chunks, and generates corresponding hash values. Contenthash changes the content in more detail, generating the corresponding hash value. Resolve a problem where the file name introduced in the chunkhash file changes due to chunkhash changesCopy the code

Author: Xiao PI Ka source: CSDN original text: blog.csdn.net/weixin_3878…