1. 程式人生 > >webpack4.x初步配置vue專案

webpack4.x初步配置vue專案

說明

參考vue-cli webpack模板, 用 webpack4.x配置了vue專案

開始

browserify不同,webpack是配置式的,所以我會先把配置檔案寫上,並在檔案裡面寫好註釋

專案結構
|-- webpack-demo
|   |-- build
|   |   |-- webpack.base.conf.js
|   |   |-- webpack.dev.conf.js
|   |   |-- webpack.prod.conf.js
|   |-- node_modules
|   |-- dist
|   |-- src
|       |-- components
|           |-- Hello.vue
|       |-- main.js
|   -- babelrc
|   -- index.html
|   -- package.json
|   -- README.md

package.json

/* webpack webpack-cli 我裝在全域性了,沒有安裝的請自行安裝  */
{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "build": "cross-env NODE_ENV=production webpack --config build/webpack.prod.conf.js",
    "dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.dev.conf.js"
}, "keywords": [], "author": "", "license": "MIT", "dependencies": { "vue": "^2.5.17" }, "devDependencies": { "babel-core": "^6.26.3", "babel-loader": "^7.1.5", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.7.0", "babel-runtime": "^6.26.0", "cross-env"
: "^5.2.0", "css-loader": "^1.0.0", "friendly-errors-webpack-plugin": "^1.7.0", "html-webpack-plugin": "^3.2.0", "mini-css-extract-plugin": "^0.4.2", "optimize-css-assets-webpack-plugin": "^5.0.0", "style-loader": "^0.22.1", "uglifyjs-webpack-plugin": "^1.3.0", "vue-loader": "^15.4.1", "vue-template-compiler": "^2.5.17", "webpack-merge": "^4.1.4" } }
公共配置
  /* build/webpack.base.conf.js */
  'use strict'
  const path = require('path')
  /*
   * 引入vue-loader plugin
   * 好像是新版本的vue-loader 需要這樣處理
   * https://vue-loader.vuejs.org/guide/#vue-cli
   */
  const VueLoaderPlugin = require('vue-loader/lib/plugin')
  /*
   * MinnCssExtractPlugin 可將 css 分離, 主要用於生產環境css的分離
   * 取代 extract-text-webpack-plugin,
   * 如果 webpack4 使用 extract-text-webpack-plugin的話,請使用
   * [email protected],據說是作者在忙,未及時更新,社群臨時使用這個
   * https://webpack.js.org/plugins/mini-css-extract-plugin/
   */
  const MiniCssExtractPlugin = require('mini-css-extract-plugin')
  const dev = process.env.NODE_ENV !== 'production'
  module.exports = {
    /* 設定入口根目錄 */
    context: path.resolve(__dirname, '..'),
    entry: {
      app: './src/main.js'
    },
    output: {
      path: path.resolve(__dirname, '../dist'),
      filename: '[name].js'
    },
    /*
     * 解析 vue
     * import Vur from 'vue' 實際上是
     * import Vue from 'vue/dist/vue.esm.js'
    */
    resolve: {
      alias: {
        'vue': 'vue/dist/vue.esm.js'
      }
    },
    module: {
      rules: [
        /*  處理.vue檔案  */
        {
          test: /\.vue$/,
          loader: 'vue-loader',
          include: [path.resolve(__dirname, '../src')]
        },
        /* babel 轉碼 */
        {
          test: /\.js$/,
          loader: 'babel-loader',
          include: [path.resolve(__dirname, '../src')]
        },
        /* 處理 css */
        {
          test: /\.css$/,
          loaders: [
            dev ? 'style-loader' : MiniCssExtractPlugin.loader,
            'css-loader'
          ],
          include: [path.resolve(__dirname, '../src')]
        }
      ]
    },
    plugins: [
      /* 好像是新版vue-loader 需要引入這個 */
      new VueLoaderPlugin()
    ]
  }
開發環境
  /* build/webpack.dev.conf.js */
  'use strict'
  const webpack = require('webpack')
  const BaseWebpackConf = require('./webpack.base.conf')
  const path = require('path')
  const merge = require('webpack-merge')
  const HtmlWebpackPlugin = require('html-webpack-plugin')
  const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')

  module.exports = merge(BaseWebpackConf, {
    /*
     * mode webpack4新內容
     * development:開啟 NamedChunksPlugin 和 NamedModulesPlugin
     * production:FlagDependencyUsagePlugin,
     *            FlagIncludedChunksPlugin,
     *            ModuleConcatenationPlugin 作用域提升
     *            NoEmitOnErrorsPlugin, 不報錯
     *            OccurrenceOrderPlugin,
     *            SideEffectsFlagPlugin
     *            UglifyJsPlugin. js壓縮
     * 預設為 production
     */
    mode: 'development',
    /*
     *  按照什麼方式生成程式碼
     *  https://webpack.js.org/configuration/devtool/
     */
    devtool: 'cheap-module-eval-source-map',
    /*
     * 配置本地伺服器
     * https://webpack.js.org/configuration/dev-server/
     */
    devServer: {
      quiet: true,
      clientLogLevel: 'warning',
      historyApiFallback: {
        rewrites: [
          {
            from: /.*/,
            to: path.resolve(__dirname, '../dist/index.html')
          }
        ]
      },
      contentBase: path.resolve(__dirname, '../dist'),
      inline: true,
      progress: true,
      hot: true,
      compress: true,
      open: true,
      proxy: {}
    },
    plugins: [
      /* 熱更新
       * https://webpack.js.org/guides/hot-module-replacement/
      */
      new webpack.HotModuleReplacementPlugin(),
      /*
       * html 模板
       * 把生成的資源插入到模板中,生成新的頁面,避免手動管理資源
       * https://webpack.docschina.org/plugins/html-webpack-plugin/
       */
      new HtmlWebpackPlugin({
        filename: 'index.html',
        template: path.resolve(__dirname, '../index.html')
      }),
      /*
       * 錯誤友好提示
       * 如果程式碼出錯了,控制檯會顯示錯誤,排版挺好看的
       * http://npm.taobao.org/package/friendly-errors-webpack-plugin
       */
      new FriendlyErrorsWebpackPlugin({
        compilationSuccessInfo: {
          messages: [
            'your application is running here http://localhost:8080 '
          ]
        }
      })
    ]
  })
生產環境
'use strict'
const webpack = require('webpack')
const merge = require('webpack-merge')
const BaseWebpackConf = require('./webpack.base.conf')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = merge(BaseWebpackConf, {
  mode: 'production',
  devtool: '#source-map',
  output: {
    path: path.resolve(__dirname, '../dist'),
    filename: 'static/js/[name].[chunkhash].js',
    chunkFilename: 'static/js/[id].[chunkhash].js'
  },
  /*
   * optimization 是 webpack4改動最大的地方了,
   * https://webpack.js.org/configuration/optimization/
   */
  optimization: {

    runtimeChunk: {
      name: 'manifest'
    },
    /*
     * minizer: 預設開啟 new UglifyJsPlugin()
     * 對 css 壓縮的話, 需要重寫 minizer
     */
    minimizer: [
      /*
       * js 壓縮
       * https://webpack.js.org/plugins/uglifyjs-webpack-plugin/
       */
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true
      }),
      /*
       * css 壓縮
       * https://www.npmjs.com/package/optimize-css-assets-webpack-plugin
       */
      new OptimizeCssAssetsPlugin({})
    ],
    splitChunks: {
      /*
       * 分離第三方資源
       */
      cacheGroups: {
        vendor: {
          name: 'vendor',
          chunks: 'all',
          priority: -10,
          reuseExistingChunk: false,
          test: /[\\/]node_modules[\\/]/
        }
      }
    }
  },
  plugins: [
    /*
     * 將css分離出來
     */
    new MiniCssExtractPlugin({
      filename: 'static/css/app.[name].css',
      chunkFilename: 'static/css/app.[contenthash].css'
    }),
    /*
     * html 模板
     */
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: path.resolve(__dirname, '../index.html'),
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
      }
    }),
    /*
     * 之前不是很理解這個外掛的用法,後來看了這篇文章
     * 主要是講多次構建程式碼的時候 如何做處理好快取
     *  https://medium.com/webpack/predictable-long-term-caching-with-webpack-d3eee1d3fa31
     */
    new webpack.HashedModuleIdsPlugin()
  ]
})
/* .babelrc */
{
  "presets":[
    [
      "env",{
          "modules":false,
      }
    ]
  ],
  "plugins":["transform-runtime"]
}

心得

webpack4.0配置開發環境還是挺簡單的,引入一些loader,再引入html-webpack-plugin,friendly-errors-webpack-plugin,
配置一下生產伺服器,啟用熱更新,基本就可以了。配置生產環境就相對麻煩一點,程式碼要分離提取壓縮,還要考慮分塊打包
,非同步載入,再次構建時快取處理等問題。相比browserify,webpack上手確實難啊,官網有些資料也更新慢了,斷斷續續看了幾天,查了好多資料,還不是特別理解,
還需要繼續琢磨吧。

文件