webpack4.0基礎篇

webpack就是爲打包而生的。css

1、準備

學習webpack首先須要安裝nodejs,而且做者也強調新版本的nodejs會提升webpack的打包速度。
安裝好node後就能夠在項目命令行中執行下面的代碼html

npm init

而後根據須要設置,也能夠一直回車,固然若是都使用默認配置也能夠node

npm init -y

這樣就能夠在項目中生成package.json文件了。這樣作的目的就是爲了使項目符合node規範。linux


2、安裝webpack

安裝webpack有兩種方式
1.全局安裝webpack(不推薦)
在命令行中輸入webpack

npm install webpack webpack-cli -g

安裝成功後能夠經過命令 webpack -v查看是否安裝成功
可是很是不推薦全局方式安裝webpack,由於若是機器上有多項目用不一樣版本webpack就沒法作到兼容。
全局卸載webpackcss3

npm uninstall webpack webpack-cli -g

2.項目內安裝webpack(==推薦==)
命令行進入項目目錄,執行下面命令es6

npm install webpack webpack-cli -D

這種方式安裝成功後沒法經過webpack -v查看webpack版本信息,由於默認node會查找全局下的webpack。這裏就要經過npx命令查看。web

npx webpack -v

npx命令會在當前項目的node_modules中找到咱們安裝的webpack正則表達式

3.安裝制定版本webpackchrome

npm install webpack@4.16.0

能夠經過webpack info 查看全部版本


3、開始打包

安裝好webpack後就能夠開始打包咱們的項目代碼了,如咱們項目中有一個xxx.js文件。

npx webpack xxx.js

這樣就會將某一個js文件進行打包,打包後的文件就存放在項目根目錄的dist文件夾中。這樣就是webpack最基礎的打包方式,使用的也是webpack默認的配置。若是想要更多的功能就要在webpack.config.js文件中進行配置


4、配置文件

在項目根目錄中新建一個webpack.config.js文件。

const path = require('path');

module.exports = {
    mode: 'production', // 打包模式,production爲生產模式,development爲開發模式 開發模式下js不會被壓縮
    // entry: 指定入口文件,
    entry: { // 打包輸出兩個文件
        home: './src/index.js',
        index: './src/index.js'
    },
    output: { // 輸入配置
        publicPath:'http://cdn.com.cn',// 指定打包的文件前綴地址
        filename:'[name].js', // 打包後的文件名,可使用placeholder佔位符方式,[name]獲取到entry中配置的名稱
        path: path.resolve(__dirname, 'dist') // 打包好的文件夾,默認就是dist
    }
}

這就是最近本的打包配置,指定的打包模式,入口,輸出配置等。
配置好後就能夠經過

npx webpack

直接運行,不用再寫具體文件,而是經過配置的入口去找到指定文件。
webpack.config.js 是webpack默認的配置文件,固然也能夠手動修改
命令行執行以下面命令便可,npx webpack --config webpackconfig2.js

在平時開發的時候可能不多有人用到npx webpack這種命令進行打包,這是由於在package.json文件中對打包命令進行了簡化,在scripts中添加以下代碼

"scripts": {
   "bundle": "webpack"
},

這樣改寫後執行npm run bundle 至關於執行了webpack打包命令。
在scripts中使用webpack會優先在項目的node_modules中找webpack。

咱們以前在安裝webpack的時候,安裝了一個webpack-cli,這個webpack-cli包的做用就是讓咱們能夠在命令行中運行webpack命令(npx webpack等命令)。


5、loader

webpack的做用就是打包,可是webpack只能識別js文件,若是咱們的js文件中引入了樣式,或者嘗試打包一個css文件、圖片文件等,那麼webpack就會報錯。由於webpack不知道如何處理這樣的文件。這時webpack就須要一個東西幫他處理,就是loader。
==loader就是幫助webpack打包不能識別的文件==

打包css

css-loader & style-loader

const path = require('path');

module.exports = {
    mode: ……
    entry: ……,
    output: ……,
    module:{
        rules:[
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            }
        ]
    } 
}

想打包css文件就要安裝style-loader和css-loader。

npm install style-loader css-loader -D

rules數組中就是不少打包規則,經過正則表達式匹配到css文件,而後告訴webpack一旦遇到css文件就使用style-loadercss-loader處理。
css-loader的做用是幫助webpack識別css。分析文件關係,而後合併。
style-loader的做用是獲得css-loader分析出來的結果,將css掛載到html-header-style中。
==因此loader的調用是有順序的,順序是從後向前==,先執行css-loader再執行style-loader。

sass-loader
打包sass文件須要用到sass-loader。首先安裝sass-loader和node-sass。
npm i sass-loader node-sass -D
而後改動一下rules

rules:[
    {
        test: /\.css$/,
        use: [
                'style-loader',
                {
                    loader: 'css-loader',
                    options: {
                        importLoaders: 1,
                        modules: true // 默認false,引入的css屬於全局的樣式,開啓true後,css變爲模塊化,引入css時能夠經過style.xxx
                    }
                },
                'sass-loader'
            ]
    }
]

sass-loader的調用必定要在css-loader以前,因此要放到數組最後。可是若是一個scss文件中經過import了另外一個scss文件,那麼在打包第二個scss文件就會直接走到css-loader,致使打包失敗。因此要在css-loaderoptions中加入importLoaders,表示走css-loader前還要走另一個loader。

postcss-loader
postcss-loader能夠自動添加css3前綴,須要新建一個postcss.config.js文件,而且要安裝插件, npm i autoprefixed -D
將postcss-loader放到rules中sass-loader以前執行,也就是數組最後。
postcss.config.js

module.exports = {
    plugins: [require('autoprefixer')]
}

這樣咱們在打包css代碼時,就會自動添加css3前綴。由於autoprefixer中內置了瀏覽器兼容表,默認>5%兼容。

打包文件

file-loader & url-loader
先安裝npm i file-loader -D。打包圖片文件以下

rules: [
    {
        test: /\.(jpg|png|gif)$/,
        use: {
            loader: 'file-loader',
            option: {
                name: '[name]_[hash].[ext]',
                outputPath: 'images/'
             }
        }
    }
]

name命名使用placeholder-佔位符,不指定則打包後的文件是隨機生成的名字。
對於特別小的圖片,可使用url-loader打包成base64格式放到js文件中。
先安裝npm i url-loader -D,file-loader的功能url-loader一樣也能夠實現,經過配置大小限制,若是超過則使用傳統方式打包,不然就使用base64方式打包,十分方便。

rules: [
    {
        test: /\.(png|jpg|gif)$/,
        use:{
            loader: 'url-loader',
            options:{
                name: '[name]_[hash].[ext]',
                outputPath: 'images/',
                limit: 2048 // 限制文件大小小於2048字節,使用base64方式打包
            }
        }
    }
]
打包es6

安裝babel-loader 和 babel/core 包。
npm i babel-loader @babel/core -D
babel-loader是幫助webpack打包的工具
babel/core是babel的核心庫。可讓babel識別js中的語法,將js語法轉換爲AST抽象語法樹。
添加babel-loader分析js語法,打通babel和webpack,同時還須要藉助其餘babel模塊才能將es6 轉換爲 es5。安裝babel/preset-env
npm i @babel/preset-env -D
如今就能夠將es6轉換爲es5了,可是一些方法在低版本的瀏覽器中依然不支持。還須要藉助polyfill模塊。
npm i @babel/polyfill -D
而後在業務代碼中引入polyfill
import "@babel/polyfill"
而後改寫webpack.config.js

rules: [
    {
        test: /\.js$/,
        exclude: /node_modules/, // 排除node_modules中的代碼
        loader: 'babel-loader',
        options:{
            presets:[["@babel/preset-env"],{
                 targets:{
                     chrome: ">67" // 能夠指定兼容瀏覽器版本
                 },
                 // 當使用polyfill的時候,會將全部特性都加入,而不是根據業務代碼決定加什麼,致使打包後的文件過大。因此經過以下配置解決這個問題,根據業務代碼的須要將使用的特性打包進去
                 useBuiltIns: 'usage'
            }]
        }
    }
]

如今就能夠正常打包es6的代碼了。不過依然會有一個潛在的問題,就是polyfill再注入方法的時候經過全局變量的形式完成的,會污染全局環境,不適用組件打包。
解決辦法:
npm i @babel/plugin-transform-runtime @babel/runtime @babel/runtime-corejs2 -D
在babel options中添加plugins配置。

rules: [
    {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options:{
            // 庫代碼使用此配置,解決polyfill的問題
            "plugins": [["@babel/plugin-transform-runtime"], {
                "corejs": 2,
                "helpers": true,
                "regenerator": true,
                "useESModules": false
            }]
        }
    }
]

補充:options內的配置能夠單獨放到.babelrc文件中


6、plugin

plugin相似一些框架中的生命週期函數,在打包特定的時間點觸發去作一些事情。

HtmlWebpackPlugin
如html-webpack-plugin是在打包結束後。安裝這個插件。
npm i html-webpack-plugin -D
HtmlWebpackPlugin插件會在打包結束後,自動生成一個html文件,並把打包生成的js自動引入到這個html中,html中沒有標籤。也能夠經過模版template,這樣在生成html文件時會以配置的html文件爲模版生成。

const path = require('path');

module.exports = {
    mode: ……
    entry: ……,
    output: ……,
    module: ……,
    plugins: [
        new HtmlWebpackPlugin({
            // 根據模版生成html文件
            template: 'src/index.html'
        })
    ] 
}

CleanWebpackPlugin
CleanWebpackPlugin插件會在打包前將dist目錄刪除(非官方)
cnpm i clean-webpack-plugin -D

module.exports = {
    mode: ……
    entry: ……,
    output: ……,
    module: ……,
    plugins: [
        // 從新打包先刪除dist目錄
        new CleanWebpackPlugin(['dist'])
    ] 
}

7、sourceMap

sourceMap 是一個映射關係,他知道dist目錄下main.js文件出錯位置,對應的是src下的index.js文件的位置。在webpack.config.js中添加devtool配置。

module.exports = {
    mode: ……
    devtool: 'none'
}

設置devtool: 'none',js報錯只會提示在打包後的js文件中,在開發的時候定位錯誤就變得異常困難。
設置devtool: 'source-map',js報錯會顯示在原來的文件中,由於在打包後的目錄中會生成一個map.js文件,裏面存的就是映射關係。報錯時經過映射關係找到原文件。
設置devtool: 'inline-source-map',inline這種方式不會生成map文件,而是生成base64字符串保存在打包後的js文件底部。
設置devtool: 'cheap-source-map',如不設置cheap,報錯信息會具體到行列,致使映射關係複雜,耗費性能。加上cheap解決這個問題,同時不去處理第三方代碼,只處理業務代碼。到一些業務須要將咱們本身寫的模塊或者第三方代碼進行處理。那就要用到module。
設置devtool: 'cheap-module-source-map',設置module後解決cheap不處理第三方模塊的問題。
設置devtool: 'cheap-module-eval-source-map',設置eval後,不會生成map文件,也不會有base64編碼的字符串,而是改變代碼的執行方式,經過sourceURL指向原文件。性能最好。
==開發環境最佳實踐==:devtool: 'cheap-module-eval-source-map'
==生產環境最佳實踐==:devtool: 'cheap-module-source-map'


8、devServer

每次修改後都要從新手動打包,這樣很是浪費時間。有三種方式解決這個問題

1.在package.json中添加"watch": "webpack --watch"

scripts:{
   "watch": "webpack --watch"
}

打包的時候運行命令npm run watch
這時webpack就會監聽要打包的文件,若是文件變化就會從新打包。

2.配置 devServer
安裝dev-server 執行。npm i webpack-dev-server -D
在package.json中添加配置

scripts:{
   "start": "webpack-dev-server"
}

打包的時候運行命令npm run start
同時也能夠在webpack.config.js中添加配置,

module.exports = {
    ……
    devServer: {
        contentBase: './dist', // 打包文件目錄
        open: true, // 是否自動打開瀏覽器
        prot: 8080 // 啓動服務端口
    }
}

==webpack-dev-server 打包後不會生成dist目錄,而是在內存中。提高打包速度==
使用dev-server時能夠搭配使用Hot Module Replacement (熱模塊替換)
引入HotModuleReplacementPlugin插件,可開啓hmr功能,hmr能夠熱更js、css等代碼。

module.exports = {
    ……
    devServer: {
        contentBase: './dist', // 打包文件目錄
        open: true, // 是否自動打開瀏覽器
        prot: 8080, // 啓動服務端口
        hot: true, // 開啓hmr
        hotOnly: true // 阻止瀏覽器自動刷新
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ],
}

3.本身編寫node服務
本身編寫服務如server.js ,在package.json中配置server命令
"server": "node server.js",至關於在node中使用webpack
打包時執行命令npm run server便可。

9、總結

webpack基礎用法就是這些,文中涉及到的內容足夠知足一個小型項目的打包需求。基礎用法熟練掌握後,能夠經過閱讀webpack官方文檔進行更詳細的打包配置。

相關文章
相關標籤/搜索