一、webpack4初識
1.首先先了解幾個規範
ES規範,導出:export default Header;
導入:import Header from ‘./header.js’;
CommonJS規範,導出:module.exports = Header;
導入:var header = require('./header.js');
其他規範CMD,AMD
2.給出一個小的項目
如果該項目不用webpack打包根本並不會正確運行,因爲瀏覽器並不會識別導入導出的js語法,但是webpack可識別這些語法
首先 npm init 初識化項目,然後npm install webpack webpack-cli -D/--save-dev 進行安裝webpack
將index.js文件打包,npx webpack index.js
這時候在導入生成的dist目錄下的main.js即可正常運行項目
但是就會有人說了,那webpack不就是js的翻譯器麼,這樣說其實是誇大了他的功能,因爲他只能識別很少部分js
二、webpack的安裝
1.全局安裝:npm install webpack webpack-cli -g
缺點:一旦全局安裝,如果一個項目webpack3,一個項目webpack4 有一個項目就跑不起來了
在項目中安裝npm install webpack webpack-cli -D/--save-dev
2.小點補充:(1)npm info webpack 可以車看webpack中所有的版本
(2)npm install webpack@xxxxx webpack-cli -D版本號安裝
(3)一般github的項目中都沒有node_moudle文件,想讓項目跑起來,在項目中執行命令 npm install 即可
三、簡單利用webpack配置文件
配置文件webpack.config.js和package.js文件的配置和修改,以及目錄結構的變化
修改了package.js中的scripts中的啓動命令後就不用npx webpack 了用npm run boundle 即可
補充,上邊的入口配置實際是簡寫,寫全是main:xxx,然後模式默認爲mode:production (js文件壓縮形式) mode:development(js不壓縮)
四、file-loader(可用於圖片打包) url-loader
url-loader的使用和file-loader類似,特別之處在於:url-loader如果未超過限定的大小,回打包到js文件中,這樣一個小的圖片文件就不會在發送一次http請求了;如果超過了限定大小,會打包到image文件夾下,這樣不會使js文件過大,不會導致頁面出現一大段時間的空白。
webpack.config.js文件
module:{
rules:[{
test:/\.(png|jpg|gif)$/,
use:{
loader:'file-loader',
options:{
name:'[name]_[hash].[ext]',
outputPath:'images/'
}
}
}]
},
module:{
rules:[{
test:/\.(png|jpg|gif)$/,
use:{
loader:'url-loader',
options:{
name:'[name].[ext]',
outputPath:'images/',
limit:2048
}
}
}]
},
這裏的2048是2kb
五、css-loader等等樣式打包
1.先介紹簡單的css打包
npm install style-loader css-loader -D
2.接下來介紹一下更高級一點的,比如sass、less等等
npm install sass-loader node-sass --save-dev
{
test:/\.scss$/,
use:['style-loader','css-loader','sass-loader']
}
3.對於一些css3新特性的使用(加前綴,-webkit- -moz-):
npm install -D postcss-loader
但還有引用第三方的插件
npm install autoprefixer -D
然後根據官方文檔進行配置
//新建一個postcss.config.js配置文件,內容如下
module.exports = {
plugins: [
require('autoprefixer')
]
}
//webpack.config.js
{
test:/\.scss$/,
use:[ 'style-loader',
'css-loader',
'sass-loader',
'postcss-loader'
]
}
其實這些loader是有順序的,從下向上,從右向左,先是執行postcss,然後找是否是sass,接着將scss轉成css最後style掛在到頁面上
4.若在sass文件中有引入了sass文件,如果像上邊那樣配置的話,引入的那個sass文件就不會被翻譯過來了,因爲不會走下邊的sass-loader和postcss-loader這兩個loader了,直接走css-loader,如果新配置了importLoader: 2 這個意思是,不管js引入的sass文件,還是sass文件中引入的sass文件都會從下往上走進行編譯
5.只在一個作用域內使css生效,模塊化css,配置:modules:true注意引入時要給css文件加一個名字,並且引入其中的類名時要用 名字.類名
5. 關於圖標字體的使用
圖標的引入時利用了iconfont阿里圖標庫,如果第一次接觸的話可有百度一下
將下載下來的css文件引入自己需要的位置並注意除了base64以外都需要修改字體路徑,在這裏就相當於了svg、woff文件的引入,所以不用在import了,進行配置webpack.config.js
module:{
rules:[{
test:/\.(png|jpg|gif)$/,
use:{
loader:'url-loader'
}
}]
}
六、關於html-webpack-plugin、clean-webpack-plugin的使用
1.html-webpack-plugin 安裝這個插件後將在打包目錄裏自動生成index.html並將想打包的js引入進js中
npm install --save-dev html-webpack-plugin
關於配置,最常用的參數是template,以一個html文件爲模板來生成打包目錄的html
var HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
2.clean-webpack-plugin
npm install --save-dev clean-webpack-plugin
每次打包都清除之前的dist打包目錄,就不用手動刪除上一次遺留下來的東西了,同上邊的配置和引入,注意自己調整一下參數即可,注意這個的引入有點特殊。要用const { CleanWebpackPlugin } = require(‘clean-webpack-plugin’),要加一個大括號
綜上,其實plugin就相當於vue中的生命週期鉤子,在打包的不同節點自己自動執行。
七、關於source-map
他其實是一個映射關係,默認情況下他是devtool:‘none’是關閉的,即當我們的某些代碼寫錯時,打包的git不會報錯,但是控制檯會報錯,不配置的話他報錯的位置是打包後文件的位置,根本找不到在原來的那個文件有代碼錯誤,配置後便能很好的映射到原來的文件位置,查到後便可修改了。
module.exports = {
mode:'production',
devtool:'source-map'
}
還有inline-source-map等等等,自己下去了解一下
八、關於每次修改完頁面,均不用再去打包一遍了(devServe)
現在來介紹三種方法:
第一種:但是要注意項目第一次打包的之後要用 npm run watch,每次修改完就不用打包了,直接刷新頁面就行
//修改package.json中的配置項
"scripts": {
"bundle": "webpack",
"watch":"webpack --watch"
}
第二種:devServer,這種他會自動開啓一個服務器,對比上一中的好處是都不用刷新了,實時更新修改
配置webpack.config.js devServer:{ contentBase :‘./dist’}
package.json "start":"webpack-dev-server"
九、HotMoudleReplacement熱模塊替換
用devServer打包時會發現沒有dist目錄了,這是因爲他自動存入了內存,從而使打包速度更快,若想看到dist目錄,就用
npx webpack
模塊配置:
const webpack = require('webpack');
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
new CleanWebpackPlugin(),
new webpack.HotModuleReplacementPlugin()
],
devServer:{
contentBase:'./dist',
open:true,
hot:true,
hotOnly:true//即使HMP不生效,瀏覽器也不會自動刷新
}
若css效果發生了改變,頁面只會刷新使用的那部分css,不會刷新整個頁面,注意這個插件是webpack自帶的,所以不用安裝,但是要require(‘webpack’),配置時用new webpack.HotMoudleReplacementPlugin()
上面只是介紹的css文件改變時,應該怎麼辦,但其實也可能一個index.js中引入過了js文件,其中一個引入的一個js文件發生變化時,如果還按照上面的方法配置將會導致文件改變頁面也沒有效果,所以這樣做
//index.js中的內容
import counter from './counter.js';
import number from './number.js';
counter();
number();
//若在開發過程中number.js發生變化
if(module.hot){
module.hot.accept('./number', () => {
//保證將上一次產生的結果清除掉
document.body.removeChild(...);
number();
})
}
之所以css不用這樣寫,是因爲css-loader已經幫忙實現了,就不用自己寫了
十、babel ES6
將由於一些比較不夠與時俱進的瀏覽器無法識別ES6語法,轉換爲ES5的語法,關於配置可參照babel的官方網站 Setup-webpack
首先進行安裝
npm install --save-dev babel-loader @babel/core
npm install @babel/preset-env --save-dev
webpack.config.js配置
{
test: /\.js$/,
exclude: /node_modules/, //如果js文件時在node_modules文件中,就不試用babel-loader了第三方的模塊沒有必要轉ES5
loader: "babel-loader" ,
options:{
"presets": ["@babel/preset-env"]
}
這樣打包就可以了,ES6的語法變成了ES5的語法,但是光是這樣子是不夠的,例如promise這種在低版本的瀏覽器中還是不存在的,所以不僅要用@babel/preset-env做語法的轉換,還要講這些確實的東西補充進低版本瀏覽器中,使用@babel/polyfill,首先進行安裝
npm install --save @babel/polyfill
但是問題又來了,打包後的文件特別大,是因爲我們將除了promise和map的其他方法也打包進來了,但我們這個項目的業務代碼只用到了promise和map所以我們只需這兩個就行,就需要一個配置參數
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options:{
presets: [['@babel/preset-env',{
useBuildIns:'usage'
}]]
}
}
還有一個問題是,如果你開發類庫組件庫時,用這種方案是有問題的,因爲babel-polyfill會讓浙西方法全局注入,會污染全局環境,所以我們要換一種配置方式:註釋掉import "@babel/polyfill"並安裝:
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
npm install --save @babel/runtime-corejs2
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options:{
// presets: [['@babel/preset-env',{
// useBuildIns:'usage'
// }]]
"plugins": [["@babel/plugin-transform-runtime",{
"corejs": 2,
"helpers": true,
"regenerator": true,
"useESModules": false
}]]
}
}
如果只是簡單業務代碼那麼只需要presets和import "@babel/polyfill"即可,如果是庫項目那就要寫下邊的一大堆plugins了,注意適應場景不同
我們發現babel的配置參數特別多特別長,所以我們可以吧他們放在一個文件中 .babelrc