Webpack 4 使用指南

最近想學一學Webpack,在網上看了不少相關文章,可是Webpack更新的太快了,不少文章都不適用weback新的版本,我從頭開始研究了一番,在這裏和你們分享交流一下,有錯誤的地方請指出.javascript

簡介

  • 從頭開始搭建一個Webpack項目
  • 遇到的各類警告
  • 打包js文件
  • 處理css文件
  • 插件使用
  • 提取公共js庫
  • webpack-dev-server 等...

一 . 搭建一個webpack項目

首先你須要一個node.js (個人版本 node v8.9.4, npm v5.6.0 )
建立一個文件夾 mkdir webpack-my 進入文件夾 cd webpack-my
建立項目 npm init 一路回車
安裝webpack webpack-cli(想要執行webpack的命令必須有這個包)
--save-dev 是隻添加依賴到開發環境
npm install --save-dev webpack webpack-cli
window下執行應該有幾條警告 警告雖然沒多大關係但咱們仍是來看一下
WARN nomnom@1.8.1: Package no longer supported... nomnom包過期了不用管它
WARN babel-preset-es2015@6.24.1 babel推薦讓使用 babel-preset-env 咱們下面再安裝
WARN webpack-my@1.0.0 No repository field 沒有倉庫地址的警告能夠在 npm init命令裏設置或修改package.json:
css

"repository": {
    "type": "git",
    "url": "http://path.xxx"
}
複製代碼

或者設置 "private": true 設置爲私有
webpack-my@1.0.0 No description 沒寫描述,基本同上...
兩個 WARN SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 fsevent是mac osx系統的,警告忽略之... (微強迫症,警告不看全不舒服...)html

二 . 處理js文件

1 . 安裝babel

處理js文件咱們須要用到bable,先安裝一下
npm install --save-dev babel-loader babel-core
java

2 . 安裝 babel-preset-env

它用來轉義es6等 babel-preset-env介紹
npm install --save-dev babel-preset-env
在根目錄下建立 .babelrc 文件, 加入如下代碼
node

{
    "presets": ["env"]
}
複製代碼

3 . 解決瀏覽器兼容及性能問題

爲防止瀏覽器不支持 Promise/Object.assign/Array.from等還有性能問題,咱們引入兩個包:
webpack

npm install --save-dev babel-polyfill babel-plugin-transform-runtime
引入生產版本依賴 npm install --save babel-runtime 經過 .babelrc 添加配置git

{
    "presets": [
        "env"
    ],
    "plugins": [
       "transform-runtime"
    ]
}
複製代碼

babel-polyfill 須要在 webpack中配置下面會說到es6

4 . 讓咱們來配置一下webpack :

建立 src/bundle文件夾做爲咱們存放/生成代碼的地方
建立 webpack.config.js 文件做爲webpack的配置文件
path爲node.js內置的,用來處理路徑的, __dirname是node.js的全局屬性,表明當前路徑。
將 babel-polyfill 加到你的 entry 數組中使用
配置js文件要通過babel轉義github

const path = require('path');
module.exports = {
    //entry爲入口,webpack從這裏開始編譯
    entry: [
        "babel-polyfill",
        path.join(__dirname, './src/index.js')
    ],
    //output爲輸出 path表明路徑 filename表明文件名稱
    output: {
        path: path.join(__dirname, './bundle'),
        filename: 'bundle.js'
    },
    //module是配置全部模塊要通過什麼處理
    //test:處理什麼類型的文件,use:用什麼,include:處理這裏的,exclude:不處理這裏的
    module: {
        rules: [
            {
                test: /\.js$/,
                use: ['babel-loader'],
                include: path.join(__dirname , 'src'),
                exclude: /node_modules/
            }
        ]
    },
};
複製代碼

好了讓咱們來試驗一下,在src裏建立 text-0.js text-1.js text-2.js index.js 內容分別爲:web

export const Text0 = "小明";
複製代碼
export const Text1 = "在公司";
複製代碼
export const Text2 = "寫代碼";
複製代碼
import {Text0} from './text-0.js';
import {Text1} from './text-1.js';
import {Text2} from './text-2.js';

const textFun = (...arg) => {
    let P = document.createElement("p");
    P.innerHTML = arg.join(" ");
    document.getElementById('root').appendChild(P);
}
textFun(Text0,Text1,Text2);
複製代碼

5 . 使用webpack

控制檯輸入 npx webpack --config webpack.config.js npx是什麼
根據webpack.config.js打包文件
等等出現了什麼 WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/ 原來是讓咱們設置開發或者生產模式
webpack.config.js 裏設置

mode: 'development'
複製代碼

爲了方便使用咱們在 package.json 里加入webpack打包的命令方便咱們使用修改 script

"scripts": {
    "build": "npx webpack --config webpack.config.js"
 },
複製代碼

這樣再次運行咱們直接輸入 npm run build
js文件打包好了,讓咱們建立一個html頁面看看效果吧,在bundle文件夾下建立 index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    </head>
    <body>
        <div id='root'></div>
        <script type="text/javascript" src="./bundle.js" charset="utf-8"></script>
    </body>
</html>
複製代碼

注意在這裏寫了一個script標籤引入 bundle.js
打開html文件看看效果吧


若是你想看看打包出來的js文件,你能夠在 webpack.config.js 裏添加 devtool 屬性 屬性配置
圖簡單的話直接配置 devtool: '' 就能夠了.

三 . 處理less文件

1 . 安裝處理 css 相關 loader

npm install --save-dev css-loader style-loader
css-loader讓你能import css  , style-loader能將css以style的形式插入

2 . 安裝 less 相關

npm install --save-dev less less-loader

3 . 安裝 postcsspostcss-cssnext 添加瀏覽器前綴

npm install --save-dev postcss-loader postcss-cssnext
建立 postcss.config.js 加入如下代碼

module.exports = {
    plugins: {
        'postcss-cssnext': {}
    }
}
複製代碼

我在這裏嘗試 autoprefixer 插件可是好像無論用,可能還依賴別的包.

4 . 配置webpack

webpack.config.js -> module -> rules 裏添加配置
處理順序從右到左 less -> postcss -> css -> style

{
    test: /\.less$/,
    use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
}
複製代碼

四 . 插件

1 . 生成HTML插件

安裝插件
npm install --save-dev html-webpack-plugin 配置 webpack.config.js

const htmlWebpackPlugin = require('html-webpack-plugin');
...
plugins: [
    new htmlWebpackPlugin({
        filename: "index.html",  //打包後的文件名
        template: path.join(__dirname , "./src/index.html")  //要打包文件的路徑
    })
],
複製代碼

src 文件夾裏建立一個 index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    </head>
    <body>
        <div id='root'></div>
    </body>
</html>
複製代碼

html-webpack-plugin用法全解
刪除 bundle 文件夾下全部文件
從新運行 npm run build 看看效果吧

2 . 生成CSS插件

安裝插件(目前必須有@next)
npm install --save-dev extract-text-webpack-plugin@next
添加配置 webpack.config.js

const ExtractTextPlugin = require('extract-text-webpack-plugin');
...
module: {
    rules: [
        ...
        {
            test: /\.less$/,
            use: ExtractTextPlugin.extract({
                fallback: "style-loader",
                use: ['css-loader', 'postcss-loader', 'less-loader']
            })
        }
    ]
},
plugins: [
    ...
    new ExtractTextPlugin({
        filename: 'index.css'
    }),
],
複製代碼

3 . 清理打包文件插件

上述代碼所打出的包名稱一直是同樣的,很容易形成緩存問題
咱們在 webpack.config.js 中作一下修改
outoup 下的 filename: 'bundle.js'filename: 'bundle.[hash:8].js'
plugins -> ExtractTextPlugin 下的 filename: 'index.css'filename: 'index.[hash:8].css'
緩存的問題解決了,可是咱們每次生成的都是不一樣名字的文件 bundle 文件夾裏的東西愈來愈多,咱們須要一個插件來清理它.
安裝插件 npm install --save-dev clean-webpack-plugin
修改 webpack.config.js

const CleanWebpackPlugin = require('clean-webpack-plugin');
...
plugins: [
    ...
    new CleanWebpackPlugin(['bundle'])
]
複製代碼
====== 2018.09.26 update ======

4 . 代碼壓縮件插件

npm install uglifyjs-webpack-plugin -D 安裝代碼壓縮插件
修改 webpack.config.js

const uglify = require('uglifyjs-webpack-plugin');
...
plugins: [
    ...
    new uglify()
]
複製代碼

五 . 提取公共js

webpack.config.js 裏添加

output: {
    ...
    chunkFilename: '[name].[chunkhash:8].js'
},
...
optimization: {
    splitChunks: {
        cacheGroups: {
            vendor: {
                test: /[\\/]node_modules[\\/]/,
                name: 'common',
                chunks: 'all'
            }
        }
    }
},
複製代碼

參考文章 webpack4 splitChunksPlugin && runtimeChunkPlugin 配置雜記

六 . webpack-dev-server配置

安裝 webpack-dev-server
npm install --save-dev webpack-dev-server webpack.config.js 添加配置

...
devServer: {
    contentBase: path.join(__dirname, 'bundle'),  //啓動路徑
    host:'localhost',  //域名
    port: 8018,  //端口號
}
複製代碼

執行命令 npx webpack-dev-server --config webpack.config.js
爲了方便使用添加 package.json 中,加入 --color(顏色) --progress(進度) --hot(熱加載)

"scripts": {
    "build": "npx webpack --config webpack.config.js",
    "start": "npx webpack-dev-server --config webpack.config.js --color --progress --hot"
 },
複製代碼

七 . 編譯圖片

npm install --save-dev url-loader file-loader
webpack.config.js -> rules增長配置:

{
   test: /\.(png|jpg|gif)$/,
   use: [{
       loader: 'url-loader',
       options: {
           limit: 8192  //8k一下的轉義爲base64
       }
   }]
}
複製代碼

總結

到這裏一個擁有基礎功能的webpack包就建好了,後續有什麼想到的東西我會繼續更新...
之後可能會加上React , 項目的代碼放在個人github
第一次寫文章,有什麼問題請告訴我~

====== 2018.5.13 update ======

筆者回來慢慢填坑了

八 . CSS Modules 使用

使用 CSS Modules 來模塊化咱們的CSS 修改咱們的 webpack.config.js -> module -> rules

{
    test: /\.less$/,
    use: ExtractTextPlugin.extract({
        fallback: "style-loader",
-       use: ['css-loader', 'postcss-loader', 'less-loader'],
+       use: ['css-loader?modules&localIdentName=[local]-[hash:base64:5]', 'postcss-loader', 'less-loader']
    })
}
複製代碼

這樣咱們全部通過 rulesless 名字都被加了hash了
在咱們的 index.less 中加入

.module-test{
    background-color: green;
    color: blue;
}
複製代碼

對應咱們在 index.js 中加入

//替換以前的引入
import style from './index.less';

const textFun = (...arg) => {
    let P = document.createElement("p");
    P.innerHTML = arg.join(" ");
+   P.className = style["module-test"];
    document.getElementById('root').appendChild(P);
}
複製代碼

運行 npm run build
好了咱們遇到一個問題,以前寫的 #root 也被 CSS Modules 改變了 但是咱們的 #root 是寫在 index.html 裏的
咱們把 #root 改爲這樣 :global(#root) 這樣就不會被改變了.

====== 2018.5.20 update ======

後續暫時沒什麼時間繼續更新文章了(想開新坑...)。
我作了一些關於多頁面打包、公共庫提取、公共代碼提取的配置
在個人 github
歡迎來訪,同時求個star 求個Fork

====== 2018.07.15 update ======

熱加載設置
webpack.config.js 中的 devServer 加入 hot: true
entry 入口添加 webpack/hot/only-dev-server 開啓熱加載
須要熱加載的頁面加入

if (module.hot) {
    module.hot.accept();
}
複製代碼

開啓熱加載

注意這種配置在多頁面狀況下只有首頁能夠熱模塊加載 其餘的頁面不行

====== 2018.07.16 update ======

加上 source-map 能看清楚錯誤在哪一個文件
devtool: 'source-map'

參考文章

Webpack4 那點兒東西
從零搭建React全家桶框架教程
webpack中文網
babel中文網

相關文章
相關標籤/搜索