webpack初入

版權聲明: https://blog.csdn.net/Ivana_zyf/article/details/80461969

npm之後發生了什麼?

我們運行vue-cli腳手架搭建的項目時通常會使用npm run dev,接下來我就簡單介紹一下之後發生的事情:

入口package.json

  • npm run XXX是去執行package.json中的腳本

package.json

在package.json裏會有這樣一段代碼:
"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "build": "node build/build.js"
  },
執行npm run dev實際上是去運行build目錄下的webpack.dev.conf.js文件

webpack.dev.conf.js

const utils = require('./utils')    //一些工具方法
const webpack = require('webpack')  //核心編譯工具
const config = require('../config') //運行時和開發時的一些配置
const merge = require('webpack-merge')//合併配置文件
const path = require('path')        //提供文件路徑操作的方法
const baseWebpackConfig = require('./webpack.base.conf')//運行和開發共享的的webpack配置文件

//webpack提供的一些插件
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')// 操作html文件的插件
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')

Object.keys(baseWebpackConfig.entry).forEach(function (name) {    // 啓用熱加載       
  baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})
module.exports = merge(baseWebpackConfig, {
  module: {   //通過傳入一些配置來獲取rules配置,此處傳入了sourceMap: false,表示不生成sourceMap
    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
  },
  devtool: '#cheap-module-eval-source-map',// 指定sourceMap類型 方便源碼定位
  plugins: [                   // 一些額外的插件,不是必須的
    new webpack.DefinePlugin({            // 編譯時配置的全局變量
      'process.env': config.dev.env   //當前環境爲開發環境
    }),
    new webpack.HotModuleReplacementPlugin(),  // 熱更新插件
    new webpack.NoEmitOnErrorsPlugin(),    // 不觸發錯誤,即編譯後運行的包正常運行,編譯出錯時跳過那部分代碼
    new HtmlWebpackPlugin({     // 以現有html爲模板去生成新的html以及相應配置,比如編譯後文件的引入
      filename: 'index.html', //生成的文件名
      template: 'index.html', //模板
      inject: true            // 表示css、js路徑自動添加到該html文件裏(css->header標籤,js->body),也可配置
    }),
    new FriendlyErrorsPlugin()                  // 友好的錯誤提示
  ]
})

webpack.base.conf.js

module.export = {
        // webpack的一些基本配置
}
  • 入口配置entry
 entry: {
      app: './src/main.js'      // 表示webpack編譯的入口js文件
  }                             
  • 輸出配置output
output: {
    path: config.build.assetsRoot,      //輸出文件的路徑
    filename: '[name].js',              //輸出的文件名,name對應entry的key
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath    //運行時
      : config.dev.assetsPublicPath    //開發時
  },                               
  • resolve 代碼中模塊的一些相關配置
resolve: {
    extensions: ['.js', '.vue', '.json'], //自動補全文件後綴名
    alias: {
      '@': resolve('src'),                //提供別名,縮短字符串長度
    }
  },
  • module 模塊解析配置,如何處理項目不同類型的模塊
 module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,      //js文件,文件後綴名
        loader: 'babel-loader',  //需要用來處理文件的插件名
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]  //include只編譯這些目錄下的文件可能會有exclude:除去這些文件編譯剩餘的
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,  //圖片的文件大小小於10KB時會生成一個base64字串打包到編譯後的js文件裏,否則超過10KB的話會單獨生產一個文件(文件名規則:utils.assetsPath)
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      }
    ]
  },

webpack.prod.conf.js

// 針對 vue文件裏的樣式單獨拆分,這樣他們會被合併到css文件裏去
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

var env = config.build.env

var webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      },
      sourceMap: true

    // extract css into its own file
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash].css')
    }),

    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: {
        safe: true
      }

    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: config.build.index,
      template: 'index.html',
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
      },
      chunksSortMode: 'dependency'
    }),

    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module, count) {
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }

    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    }),

    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ]
})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章