Webpack 配置入門

更新:Webpack4已經(jīng)發(fā)布,本篇是基于Webpack3的,請(qǐng)注意。
更正:
1.package.json中使用了應(yīng)該使用本地webpack而不是全局webpack。

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dist": "webpack",
    "build:dll": "webpack --config webpack.config.dll.js",
    "build:dev": "webpack-dev-server --config webpack.config.dev.js --open",
    "build:pord": "webpack --config webpack.config.pord.js"
  },

應(yīng)為:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dist": "./node_modules/.bin/webpack",
    "build:dll": "./node_modules/.bin/webpack --config webpack.config.dll.js",
    "build:dev": "./node_modules/.bin/webpack-dev-server --config webpack.config.dev.js --open",
    "build:pord": "./node_modules/.bin/webpack --config webpack.config.pord.js"
  },
  1. webpack.config.js文件中output.publicPath缺失,應(yīng)為:
  output: {
    publicPath: "http://www.example.com/", // <---- 這里填寫web訪問地址,域名、IP、CDN等
    filename: '[name]_[chunkhash:20].js',               // 輸出帶20位hash的文件名
    path: path.resolve(__dirname, 'dist'),              // 輸出路徑
  },

output.publicPath會(huì)更正文件或資源的前綴,在正式部署時(shí)特別必要。

一、什么是webpack,為什么要使用它?

1.官方解釋

webpack是一個(gè)現(xiàn)代JavaScript應(yīng)用程序的模塊打包器(module bundler)。

2.個(gè)人理解

webpack是一個(gè)模塊打包機(jī):它做的事情是,分析你的項(xiàng)目結(jié)構(gòu),找到JavaScript模塊進(jìn)行處理,找到其它的模塊如css及一些瀏覽器不能直接運(yùn)行的拓展語言模塊Scss,TypeScript等,并選擇相應(yīng)的插件進(jìn)行處理,并將處理結(jié)果轉(zhuǎn)換打包為合適的格式供瀏覽器使用。

3.優(yōu)缺點(diǎn)

Grunt以及Gulp是在一個(gè)配置文件中指定對(duì)文件處理的具體流程,如校驗(yàn)->編譯->組合->壓縮等。配置比較繁瑣,但是可定制性比較高。

webpack把整個(gè)項(xiàng)目當(dāng)成整體,從入口查找文件關(guān)系,然后整體的以文件為單位使用loader對(duì)代碼進(jìn)行處理,最后打包為一個(gè)或者多個(gè)瀏覽器識(shí)別的文件。配置相對(duì)簡單,處理速度快,高級(jí)場景下定制能力有限,但是大部分情況下可以替代Grunt以及Gulp。

二、安裝webpack

1.安裝

1.1前置條件

安裝nodejs,nodejs.org,不再詳述

1.2安裝方式

在終端運(yùn)行命令:

# 全局安裝
npm install -g webpack
# 安裝到項(xiàng)目目錄
npm install --save-dev webpack

上面兩個(gè)命令可以選擇執(zhí)行一個(gè),但建議執(zhí)行兩個(gè)。項(xiàng)目中安裝一個(gè)置指定版本的webpack,全局的webpack作為備份項(xiàng)。

三、項(xiàng)目中的webpack

1.項(xiàng)目

如果已經(jīng)有npm項(xiàng)目請(qǐng)略過。

# 前往工作區(qū),[$WORKSPACE]替換為自己的工作區(qū)路徑
cd [$WORKSPACE]
# 創(chuàng)建項(xiàng)目目錄
mkdir webpack_demo
# 初始化package.json,可以一路略過
npm init

2.安裝webpack

# 安裝的項(xiàng)目目錄
npm install --save-dev webpack

3.Demo01 - Hello Webpack

建立如下目錄結(jié)構(gòu)

.
├── dist
│   └── index.html
├── package.json
├── public
└── src
    ├── Welcome.js
    └── index.js

代碼如下:

<!--index.html-->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Webpack Sample Project</title>
  </head>
  <body>
    <div id='root'>
    </div>
    <script src="bundle.js"></script>
  </body>
</html>
// index.js
import welcome from './Welcome.js'

document.querySelector("#root").appendChild(welcome());
// Welcome.js
export default function() {
  var welcome = document.createElement('div');
  welcome.textContent = "Hello webpack!";
  return welcome;
};

webpack可以通過命令行使用,可以先通過下面的方式調(diào)用:

$> node_modules/.bin/webpack src/index.js dist/bundle.js
Hash: 098382ad52c485fbdff8
Version: webpack 3.6.0
Time: 66ms
    Asset     Size  Chunks             Chunk Names
bundle.js  2.78 kB       0  [emitted]  main
   [0] ./src/index.js 96 bytes {0} [built]
   [1] ./src/Welcome.js 138 bytes {0} [built]

此時(shí)可以動(dòng)過瀏覽器訪問dist/index.html

4.Demo02 - 通過配置文件來使用webpack

webpack雖然支持使用命令行的方式配置使用,但Demo01中使用命令行的方式輸入起來還是比較繁瑣。webpack支持使用配置文件進(jìn)行參數(shù)配置。

在項(xiàng)目根目錄下創(chuàng)建webpack.config.js文件(這也是webpack的默認(rèn)配置文件):

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

然后可以執(zhí)行命令進(jìn)行編譯打包:

# 指定配置文件
./node_modules/.bin/webpack --config webpack.config.js
# 使用默認(rèn)配置文件
./node_modules/.bin/webpack
# 使用作用域最近的webpack,并且使用默認(rèn)配置文件
webpack

雖然現(xiàn)在可以直接使用webpack命令進(jìn)行打包,但是如果需要定制其他的打包配置時(shí),就會(huì)比較麻煩,這個(gè)時(shí)候可以用npm腳本。

在package.json中scripts項(xiàng)下添加:

{
  ...
  "scripts": {
    "dist": "webpack"
  },
  ...
}

此時(shí)可以通過命令行npm run dist進(jìn)行打包。

5.資源管理,loader

5.1.Demo03 - CSS樣式

CSS需要使用css-loader和style-loader進(jìn)行處理。css-loader解釋@import和url(),會(huì)import/require()后再解析它們。style-loader會(huì)把原來的CSS代碼插入頁面中的一個(gè)style標(biāo)簽中。

先安裝style-loader和css-loader

npm install --save-dev style-loader css-loader

修改webpack.config.js如下:

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },

  module: {
    rules: [{
      test: /\.css$/,
      use: [
        'style-loader',
        'css-loader'
      ]
    }]
  }
};

修改Welcome.js如下:

import './style.css';

export default function() {     // 這里之前的‘module.exports = ’寫法打包正常,但是運(yùn)行時(shí)報(bào)錯(cuò)
  var welcome = document.createElement('div');
  welcome.textContent = "Hello webpack!";
  welcome.classList.add('welcome');
  return welcome;
};

添加src/style.css文件:

.welcome {
  color: red;
}

npm run dist打包后運(yùn)行,可以看到welcome樣式已經(jīng)發(fā)生改變。

5.2.Demo04 - 圖片資源

圖片等靜態(tài)資源在開發(fā)階段時(shí)的相對(duì)路徑與生產(chǎn)環(huán)境中的不盡相同,所以需要對(duì)這些文件進(jìn)行路徑轉(zhuǎn)換,此時(shí)可以使用file-loader。另外如果圖片較多,會(huì)發(fā)送很多請(qǐng)求,而瀏覽器能夠同時(shí)發(fā)送的請(qǐng)求數(shù)有限,大量的圖片資源會(huì)降低也面性能,可以通過url-loader把部分圖片編碼打包到文件中,url-loader是對(duì)file-loader的封裝,這里使用url-loader。

安裝file-loader、url-loader:

npm install --save-dev file-loader url-loader

添加資源文件src/image/iconrar.png(105KB),src/image/iconrar.png(87KB)

修改webpack.config.js:

...
module.exports = {
...
  module: {
    rules: [
    ...
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 102400,       // 這里以100KB為分界線
              name: '[name].[ext]',
            }
          }
        ]
      }
    ...
    ]
  }
  ...
};

修改src/index.js文件:

import welcome from './Welcome.js'
import image from './Image.js'
import './style.css';

const root = document.querySelector("#root")
root.appendChild(welcome());
root.appendChild(image('image1'));
root.appendChild(image('image2'));

添加src/Image.js文件:

export default function(className) {
  var image = document.createElement('div');
  image.classList.add(className);
  return image;
}

src/style.js中添加樣式

...
.image1 {
  width: 200px;
  height: 200px;
  background-image: url('./image/iconrar.png');
  background-size: contain;
}

.image2 {
  width: 200px;
  height: 200px;
  background-image: url('./image/iconzip.png');
  background-size: contain;
}

npm run dist打包后運(yùn)行,可以看到圖片已經(jīng)添加到了頁面上。觀察dist文件夾,只有一個(gè)圖片拷貝進(jìn)來,然后再觀察bundle.js文件,會(huì)發(fā)現(xiàn)有一片圖片編碼區(qū)。

6.Demo05 - 分片打包

隨著項(xiàng)目體量的增加,整個(gè)項(xiàng)目打包為單一的bundle可能會(huì)嚴(yán)重影響首屏加載時(shí)間,這個(gè)時(shí)候可以把原來單一的bundle分為多個(gè)文件,也就是webpack分片打包。

修改webpack.config.js,在配置中添加入口,這里可以使用動(dòng)態(tài)入口,如使用node代碼遍歷代碼文件。

  ...
  entry: {
    index: './src/index.js',
    image: './src/Image.js',
    welcome: './src/Welcome.js',
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
  },
  ...

此時(shí)嘗試打包成功,但是訪問index.html異常,控制臺(tái)報(bào)錯(cuò)。因?yàn)閕ndex.html中引用的bundle.js已經(jīng)變更為三個(gè)js文件。因?yàn)檫@個(gè)入口配置可能經(jīng)常改變,手動(dòng)去dist/index.html修改script引用比較繁瑣,可以使用HtmlWebpackPlugin插件來自動(dòng)生成dist/index.html,或者使用html-webpack-template插件在模版的基礎(chǔ)上生成dist/index.html。這里使用HtmlWebpackPlugin插件。

安裝html-webpack-plugin

npm install --save-dev html-webpack-plugin

修改webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  ...
  plugins: [
    new HtmlWebpackPlugin({ title: 'Webpack Sample Project' })
  ]
  ...
};

使用html-webpack-plugin生成的dist/index.html已經(jīng)沒有id為root的div了,我們修改一下src/index.js

import welcome from './Welcome.js'
import image from './Image.js'
import './style.css';

const root = document.querySelector('body')
root.appendChild(welcome());
root.appendChild(image('image1'));
root.appendChild(image('image2'));

現(xiàn)在已經(jīng)可以使用webpack來分片打包了。webpack把打包后的內(nèi)容放置在dist目錄中,目錄中的內(nèi)容部署后,瀏覽器就能夠訪問到。但是由于瀏覽器的緩存策略,如果我們?cè)诓渴鹦掳姹緯r(shí)不更改資源的文件名,瀏覽器可能會(huì)認(rèn)為它沒有被更新,就會(huì)使用它的緩存版本。由于緩存的存在,當(dāng)你需要獲取新的代碼時(shí),就會(huì)顯得很棘手。

為了解決這一問題,我們可以使用output.filename來進(jìn)行文件名替換,來確保瀏覽器獲取到修改后的文件。

修改webpack.config.js,在輸出的文件名中加入哈希碼chunkhash

  ...
  output: {
    filename: '[name]_[chunkhash].js',
    path: path.resolve(__dirname, 'dist'),
  },
  ...

這時(shí)候打包后可以正常訪問,但是你會(huì)發(fā)現(xiàn)dist文件夾下會(huì)有很多文件,這是因?yàn)殡S著每次修改項(xiàng)目文件,項(xiàng)目文件的chunkhash發(fā)生改變,會(huì)生成新的輸出文件,但是舊有的文件沒有被清除。通過使用clean-webpack-plugin插件可以在每次打包前刪除dist文件夾。

安裝clean-webpack-plugin

npm install --save-dev clean-webpack-plugin

修改webpack.config.js

const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  ...
  plugins: [
    new CleanWebpackPlugin(['dist']),
    new HtmlWebpackPlugin({ title: 'Webpack Sample Project' })
  ]
  ...
};

現(xiàn)在完整的webpack.config.js文件如下:

const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    index: './src/index.js',
    image: './src/Image.js',
    welcome: './src/Welcome.js',
  },
  output: {
    filename: '[name]_[chunkhash].js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [{
      test: /\.css$/,
      use: [
        'style-loader',
        'css-loader'
      ]
    }, {
      test: /\.(png|svg|jpg|gif)$/,
      use: [
        {
          loader: 'url-loader',
          options: {
            limit: 102400,
            name: '[name]_[hash:20].[ext]',
            outputPath: 'image/'
          }
        }
      ]
    }]
  },

  plugins: [
    new CleanWebpackPlugin(['dist']),
    new HtmlWebpackPlugin({ title: 'Webpack Sample Project' })
  ]
};

7.Demo06 - 調(diào)試開發(fā)和熱加載HMR

生產(chǎn)環(huán)境中僅部署時(shí)需要打包一下,但是在開發(fā)環(huán)境中需要不停的運(yùn)行命令進(jìn)行打包,是一件十分繁瑣的事情,可以使用webpack-dev-server工具在代碼發(fā)生改變時(shí)自動(dòng)打包代碼。

另外,我們會(huì)在上面配置文件的基礎(chǔ)上對(duì)開發(fā)環(huán)境dev和生產(chǎn)環(huán)境pord進(jìn)行擴(kuò)展。需要使用webpack-merge模塊。

安裝webpack-dev-serverwebpack-merge

npm install --save-dev webpack-dev-server webpack-merge

創(chuàng)建webpack.config.dev.js文件:

const merge = require('webpack-merge');
const webpack = require('webpack');
const config = require('./webpack.config.js');

module.exports = merge(config, {
  devtool: 'cheap-module-eval-source-map',    // 選擇一個(gè)合適的sourcemap項(xiàng)
  output: {
    filename: '[name].js',                    // 在熱加載時(shí)不能使用chunkhash
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ],
  devServer: {
    contentBase: './dist',
    historyApiFallback: true,
    hot: true,
    inline: true,
    host: '127.0.0.1',
    port: 8080,
  }
});

修改package.json,添加npm腳本:

{
  ...
  "scripts": {
    "dist": "webpack",
    "build:dev": "webpack-dev-server --config webpack.config.dev.js --open"
  },
  ...
}

現(xiàn)在嘗試運(yùn)行npm run build:dev,瀏覽器會(huì)自動(dòng)訪問127.0.0.1:8080/index.html,即contentBase指定的目錄下的index.html文件。

8.Demo07 - 混淆壓縮和生產(chǎn)打包

生產(chǎn)環(huán)境下代碼簡單編譯打包,不經(jīng)混淆壓縮就部署,容易被別有用心的人獲取并分析代碼,可能會(huì)增加產(chǎn)權(quán)問題和安全風(fēng)險(xiǎn)。webpack自帶的uglifyjs-webpack-plugin插件可以來做混淆壓縮

安裝uglifyjs-webpack-plugin:

npm install --save-dev uglifyjs-webpack-plugin

創(chuàng)建webpack.config.pord.js文件:

const merge = require('webpack-merge');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const config = require('./webpack.config.js');

module.exports = merge(config, {
  plugins: [
    new UglifyJSPlugin()
  ]
});

修改package.json,添加npm腳本:

{
  ...
  "scripts": {
    "dist": "webpack",
    "build:dev": "webpack-dev-server --config webpack.config.dev.js --open",
    "build:pord": "webpack --config webpack.config.pord.js"
  },
  ...
}

現(xiàn)在嘗試運(yùn)行npm run build:pord,這個(gè)時(shí)候可以查看dist文件夾下的js文件,可以看到j(luò)s已經(jīng)被混淆壓縮了。同時(shí),uglifyjs-webpack-plugin實(shí)現(xiàn)了tree-shaking能力,能夠優(yōu)化掉未使用的代碼。

9.Dome08 - 公共代碼分離

公共代碼分為兩部分,一部分是三方的庫,一部分是項(xiàng)目中寫的復(fù)用程度比較高的代碼。實(shí)例項(xiàng)目中三方庫使用lodashmoment,而src/Welcome.jssrc/Image.js作為服用程度比較高的庫被單獨(dú)打包。

我們需要新建入口文件復(fù)制index.jsindex2.js,作為第二個(gè)入口文件。這樣src/Welcome.jssrc/Image.js為兩個(gè)入口公用的模塊,可以單獨(dú)打爆出來。

打包公共模塊在開發(fā)環(huán)境和生產(chǎn)環(huán)境都適用,所以修改webpack.config.js文件如下:

const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    vendor: ['lodash', 'moment'],                       // 三方庫
    common: ['./src/Welcome.js', './src/Image.js'],     // 項(xiàng)目中復(fù)用程度高的代碼
    index: './src/index.js',
    index2: './src/index2.js',
  },
  output: {
    filename: '[name]_[chunkhash:20].js',               // 輸出帶20位hash的文件名
    path: path.resolve(__dirname, 'dist'),              // 輸出路徑
  },
  module: {
    rules: [{
      test: /\.css$/,                                   // CSS loader
      use: [
        'style-loader',
        'css-loader'
      ]
    }, {
      test: /\.(png|svg|jpg|gif)$/,                     // 圖片loader
      use: [
        {
          loader: 'url-loader',
          options: {
            limit: 102400,
            name: '[name]_[hash:20].[ext]',
            outputPath: 'image/'
          }
        }
      ]
    }]
  },
  plugins: [
    new CleanWebpackPlugin(['dist']),                   // 清理dist文件件
    new webpack.optimize.CommonsChunkPlugin({           // 打包公共模塊
      names: ['vendor', 'common'],
      minChunks: 2,
    }),
    new HtmlWebpackPlugin({                             // 生成html入口
      filename: 'index.html',
      title: 'Webpack Sample Project',
      chunks: ['vendor', 'common', 'index'],
    }),
    new HtmlWebpackPlugin({                             // 生成html入口2
      filename: 'index2.html',
      title: 'Webpack Sample Project2',
      chunks: ['vendor', 'common', 'index2'],
    }),
  ]
};

此時(shí)使用命令npm run dist打包,可以查看dist文件夾下的文件,src/Welcome.jssrc/Image.js的確被打包到了commons_[chunkhash:20].js文件中,而lodashmoment也被打包到了vender_[chunkhash:20].js文件中,index_[chunkhash:20].jsindex2_[chunkhash:20].js中并不含上面兩部分代碼。

雖然這樣公共代碼已經(jīng)能夠分離了,但是,項(xiàng)目越來越大,像lodashmoment這樣的三方庫也越來越多,每次打包都需要重新生成vender.js文件,特別是在開發(fā)中,效率嚴(yán)重被拉低。

webpack提供了dll技術(shù)來解決這個(gè)問題。

添加webpack.config.dll.js:

const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  context: __dirname,
  entry: {
    vendor: ['lodash', 'moment'],                       // 三方庫
  },
  output: {
    filename: '[name]_[hash:20].js',                    // 輸出帶20位hash的文件名
    path: path.resolve(__dirname, 'dist/lib'),          // 輸出路徑
    library: '[name]_[hash:20]',
  },
  plugins: [
    new CleanWebpackPlugin(['dist/lib']),               // 清理dist文件件
    new UglifyJSPlugin(),
    new webpack.DllPlugin({
      path: path.join(__dirname, 'dist/lib', '[name]_manifest.json'),
      name: '[name]_[hash:20]',
    })
  ]
};

此時(shí)可以使用webpack --config webpack.config.dll.js命令進(jìn)行dll打包了。接下來需要使用add-asset-html-webpack-plugin插件來把上面配置文件生成的vendor_[hash:20].js寫入到html-webpack-plugin插件生成的index.html中。

安裝add-asset-html-webpack-plugin:

npm install --save-dev add-asset-html-webpack-plugin

修改webpack.config.js如下:

const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');

module.exports = {
  entry: {
    common: ['./src/Welcome.js', './src/Image.js'],     // 項(xiàng)目中復(fù)用程度高的代碼
    index: './src/index.js',
    index2: './src/index2.js',
  },
  output: {
    filename: '[name]_[chunkhash:20].js',               // 輸出帶20位hash的文件名
    path: path.resolve(__dirname, 'dist'),              // 輸出路徑
  },
  module: {
    rules: [{
      test: /\.css$/,                                   // CSS loader
      use: [
        'style-loader',
        'css-loader'
      ]
    }, {
      test: /\.(png|svg|jpg|gif)$/,                     // 圖片loader
      use: [
        {
          loader: 'url-loader',
          options: {
            limit: 102400,
            name: '[name]_[hash:20].[ext]',
            outputPath: 'image/'
          }
        }
      ]
    }]
  },
  plugins: [
    new CleanWebpackPlugin(['dist/*.*']),               // 清理dist文件件
    new webpack.DllReferencePlugin({                    // webpack Dll
      context: __dirname,
      manifest: require(path.resolve(__dirname, 'dist/lib/vendor_manifest.json')),
    }),
    new webpack.optimize.CommonsChunkPlugin({           // 打包公共模塊
      name: 'common',
      minChunks: 2,
    }),
    new webpack.optimize.CommonsChunkPlugin({           // manifest
      name: "manifest",
      minChunks: Infinity
    }),
    new HtmlWebpackPlugin({                             // 生成html入口
      filename: 'index.html',
      title: 'Webpack Sample Project',
      chunks: ['manifest', 'common', 'index'],
    }),
    new AddAssetHtmlPlugin({                            // 把dll生成的js文件拷貝到html
      files: 'index.html',
      includeSourcemap: false,
      filepath: path.resolve(__dirname, './dist/lib/*.js'),
    }),
    new HtmlWebpackPlugin({                             // 生成html入口2
      filename: 'index2.html',
      title: 'Webpack Sample Project2',
      chunks: ['manifest', 'common', 'index2'],
    }),
    new AddAssetHtmlPlugin({                            // 把dll生成的js文件拷貝到html
      files: 'index2.html',
      includeSourcemap: false,
      filepath: path.resolve(__dirname, './dist/lib/*.js'),
    }),
  ]
};

為了體現(xiàn)lodashmoment能夠正常使用:

修改src/Welcome.js

import moment from 'moment';
import _ from 'lodash';

export default function() {
  var arr = [0, 1, 2];
  _.fill(arr, 0);
  arr[1] = [moment().format('YYYY-MM-DD')];

  var welcome = document.createElement('div');
  welcome.textContent = 'Hello webpack!' + arr.join(' <> ');
  welcome.classList.add('welcome');
  return welcome;
};

添加npm腳本:

  "scripts": {
    "dist": "webpack",
    "build:dll": "webpack --config webpack.config.dll.js",
    "build:dev": "webpack-dev-server --config webpack.config.dev.js --open",
    "build:pord": "webpack --config webpack.config.pord.js"
  },

這樣,第一次打包前運(yùn)行npm run build:dll生成vendor包,然后運(yùn)行npm run build:devnpm run build:pord進(jìn)行開發(fā)打包或部署打包。

10.Demo09 - CSS分離

安裝add-asset-html-webpack-plugin:

npm install --save-dev extract-text-webpack-plugin

修改webpack.config.js如下:

...
const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
  ...
  module: {
    rules: [{
      test: /\.css$/,                                   // CSS loader
      use: ExtractTextPlugin.extract({
        fallback: "style-loader",
        use: "css-loader"
      })
    }, {
      test: /\.(png|svg|jpg|gif)$/,                     // 圖片loader
      use: [
        {
          loader: 'url-loader',
          options: {
            publicPath: path.resolve(__dirname, 'dist'),// 這里需要修正image的publicPath
            limit: 102400,
            name: '[name]_[hash:20].[ext]',
            outputPath: '/image/'
          }
        }
      ]
    }]
  },
  plugins: [
    new CleanWebpackPlugin([                            // 清理dist文件件
      'dist/*.*',
      'dist/image/*.*',
      'dist/style/*.*'
    ]),
    new ExtractTextPlugin({                             // CSS分離
      filename: 'style/[name]_[contenthash:20].css',
    }),
    ...
  ]
};

前往webpack.config.dev.js,把默認(rèn)config中實(shí)例化的CleanWebpackPlugin給splice掉,就可以在npm run dist、npm run build:dev、npm run build:pord三個(gè)環(huán)境下進(jìn)行打包了。

Demo: https://github.com/HermitCarb/webpack_demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容