webpack 配置基礎-代碼分離

我的系列博客連接javascript


title:webpack基礎css


1 webpack CLI (Command Line Interface)

經常使用配置

webpack --help (webpack -h)  列出命令行全部可用的配置選項
webpack --config example.config.js
webpack 命令默認執行  webpack.config.js

環境變量. nodeProcess.env

webpack --env.production    # 設置 env.production == true
webpack --env.platform=web  # 設置 env.platform == "web"
webpack --env.NODE_ENV=local --env.production --progress
若是設置 env 變量,卻沒有賦值,--env.production 默認將 --env.production 設置爲 true

其餘配置

配置文件多種配置類型-對象,函數html

2管理資源

+ |– /components
+ |  |– /my-component
+ |  |  |– index.jsx
+ |  |  |– index.css
+ |  |  |– icon.svg
+ |  |  |– img.png

這種配置方式會使你的代碼更具有可移植性,由於現有的統一放置的方式會形成全部資源緊密耦合在一塊兒。假如你想在另外一個項目中使用 /my-component,只需將其複製或移動到 /components 目錄下。vue

3 webpack 緩存管理連接

4 代碼分離

重點:java

1 bundle 分析(bundle analysis) 先學會如何利用這個插件來了解webpack的打包狀況;node

2 以ele提供模版參考element-starterwebpack

參考官網git

  • 入口起點:使用 entry 配置手動地分離代碼。
  • 防止重複:使用 CommonsChunkPlugin 去重和分離 chunk。
  • 動態導入:經過模塊的內聯函數調用來分離代碼。
npm run dev
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>element-starter</title>
</head>

<body>
  <div id="app"></div>
<script type="text/javascript" src="/assets/index.js"></script>
<script type="text/javascript" src="/assets/vendor.js"></script></body>

</html>
  • 啓動項目以後,在控制檯查看network分析
  • 入口文件生成的不一樣的bundle都被動態的添加到index.html中,加載index.html以後,經過script進行加載

性能優化:github

  • entry有幾個入口起點,就會在index.html中動態插入幾個bundle,能夠經過拆分bundle,減小bundle的大小
  • 假如a.js. b.js 都引入了 import lodash from 'lodash'

注意:HtmlWebpackPlugin插件會先將 多個入口的公用庫 在經過 CommonsChunkPlugin插件提取公共bundle的時候,優先導入index.html文件web

4.1 入口起點(沒有設置CommonsChunkPlugin插件的時候)

注意:

  • 若是傳入一個字符串或字符串數組,chunk 會被命名爲 main
entry:'./src/main.js',
<script type="text/javascript" src="vendorddd.js?1e2bb5c4a74e8d3950a2"></script><script type="text/javascript" src="main.js?363487fd4d1508087ee4"></script>
  • 若是傳入一個對象,則每一個鍵(key)會是 chunk 的名稱,該值描述了 chunk 的入口起點。
entry: {
    index: './src/main.js',
    vendor: './src/vendor'  
},
    //or
entry: {
    vendor: './src/vendor',
    index: './src/main.js',
},

以上根據HtmlWebpackPlugin插件生成的都是以下:

<script type="text/javascript" src="index.js?0404cb6d254c943fe5f4"></script><script type="text/javascript" src="vendor.js?de6b638d85297a1b138b"></script></body>

若是使用 CommonsChunkPlugin插件 ,那麼webpack生成的chunk中會有 manifest 和 runtime 這兩個chunk

new webpack.optimize.CommonsChunkPlugin({
    names:  ['vendor','manifest','runtime']
}),

4.2 入口起點設置CommonsChunkPlugin插件

接受配置以下:

{
  name: string, // or
  names: string[],
  // 這是 common chunk 的名稱。已經存在的 chunk 能夠經過傳入一個已存在的 chunk 名稱而被選擇。
  // 若是一個字符串數組被傳入,這至關於插件針對每一個 chunk 名被屢次調用
  // 若是該選項被忽略,同時 `options.async` 或者 `options.children` 被設置,全部的 chunk 都會被使用,
  // 不然 `options.filename` 會用於做爲 chunk 名。
  // When using `options.async` to create common chunks from other async chunks you must specify an entry-point
  // chunk name here instead of omitting the `option.name`.

  filename: string,
  // common chunk 的文件名模板。能夠包含與 `output.filename` 相同的佔位符。
  // 若是被忽略,本來的文件名不會被修改(一般是 `output.filename` 或者 `output.chunkFilename`)。
  // This option is not permitted if you're using `options.async` as well, see below for more details.

  minChunks: number|Infinity|function(module, count) -> boolean,
  // 在傳入  公共chunk(commons chunk) 以前所須要包含的最少數量的 chunks 。
  // 數量必須大於等於2,或者少於等於 chunks的數量
  // 傳入 `Infinity` 會立刻生成 公共chunk,但裏面沒有模塊。
  // 你能夠傳入一個 `function` ,以添加定製的邏輯(默認是 chunk 的數量)

  chunks: string[],
  // 經過 chunk name 去選擇 chunks 的來源。chunk 必須是  公共chunk 的子模塊。
  // 若是被忽略,全部的,全部的 入口chunk (entry chunk) 都會被選擇。


  children: boolean,
  // 若是設置爲 `true`,全部  公共chunk 的子模塊都會被選擇

  deepChildren: boolean,
  // If `true` all descendants of the commons chunk are selected

  async: boolean|string,
  // 若是設置爲 `true`,一個異步的  公共chunk 會做爲 `options.name` 的子模塊,和 `options.chunks` 的兄弟模塊被建立。
  // 它會與 `options.chunks` 並行被加載。
  // Instead of using `option.filename`, it is possible to change the name of the output file by providing
  // the desired string here instead of `true`.

  minSize: number,
  // 在 公共chunk 被建立立以前,全部 公共模塊 (common module) 的最少大小。
}
4.2.1 提取多入口公共部分,會額外生成一個 chunk(每一個入口都會生成一個chunk)
entry: {
    app: './src/app',
    index: './src/main.js',
},
new webpack.optimize.CommonsChunkPlugin({
    name:'commons'
}),
<script type="text/javascript" src="commons.js?72cc5aafa56e436c4610"></script><script type="text/javascript" src="index.js?db019f512b2790009263"></script><script type="text/javascript" src="app.js?34b940d4b77ffe921124"></script></body>

以上會將app.jsindex.js的公用部分提取出來;

4.2.2 設置公用庫
entry: {
    vendor: ['lodash','vue'],
    index: './src/main.js',
},
new webpack.optimize.CommonsChunkPlugin({
    name:'vendor'
}),

能夠發現經過 CommonsChunkPlugin 明確第三方庫 chunk,而且會優先加載

<script type="text/javascript" src="vendor.js?2f90511bd9c96a3ace4b"></script><script type="text/javascript" src="index.js?db019f512b2790009263"></script></body>
4.2.3 公用庫的bundle緩存配置 官方連接
entry: {
    vendor: ['lodash','vue'],
    index: './src/main.js',
  },
new webpack.NamedModulesPlugin(),    
    new webpack.optimize.CommonsChunkPlugin({
    names:  'vendor'
}),
    new webpack.optimize.CommonsChunkPlugin({
    names:  'manifest'
}),

webpack.config.js

const resolve = require('path').resolve
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const url = require('url')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const publicPath = ''

module.exports = (options = {}) => ({
  // entry:'./src/main.js',
  entry: {
    vendor: ['lodash','vue'],
    
    index: './src/main.js',
    
  },
  output: {
    path: resolve(__dirname, 'dist'),
    //entry 入口文件導出的文件名會以這個爲準
    filename: options.dev ? '[name].js' : '[name].js?[chunkhash]',
    //非入口文件導入的文件,好比動態導入的文件,會以這個爲準
    chunkFilename: '[name].js?[chunkhash]',
    publicPath: options.dev ? '/assets/' : publicPath
  },
  module: {
    rules: [{
        test: /\.vue$/,
        use: ['vue-loader']
      },
      {
        test: /\.js$/,
        use: ['babel-loader'],
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      },
      {
        test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,
        use: [{
          loader: 'url-loader',
          options: {
            limit: 10000
          }
        }]
      }
    ]
  },
  plugins: [
    new webpack.NamedModulesPlugin(),    
    new webpack.optimize.CommonsChunkPlugin({
      names:  'vendor'
    }),
    new webpack.optimize.CommonsChunkPlugin({
      names:  'manifest'
    }),
    new HtmlWebpackPlugin({
      template: 'src/index.html'
    }),
    new BundleAnalyzerPlugin()
  ],
  resolve: {
    alias: {
      '~': resolve(__dirname, 'src')
    },
    extensions: [".js", ".json",".vue"]

  },
  devServer: {
    host: '127.0.0.1',
    port: 8010,
    proxy: {
      '/api/': {
        target: 'http://127.0.0.1:8080',
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    },
    historyApiFallback: {
      index: url.parse(options.dev ? '/assets/' : publicPath).pathname
    }
  },
  devtool: options.dev ? '#eval-source-map' : '#source-map'
})
相關文章
相關標籤/搜索