Webpack基礎(chǔ)

1窿克、webpack的安裝

本教程是基于最新的webpack4.39.3 版本

注意:webpack是基于node的则北,所以使用前請先自行安裝nodejs環(huán)境

  • 全局安裝webpack(不推薦)

    npm i webpack webpack-cli -g

  • 項目中安裝webpack (推薦)

    新建一個空文件涝缝,然后初始化npm init -y初始化一個package.json文件

    然后去下載npm i webpack webpack-cli -D

2别洪、webpack的使用

①.webpack-cli

npm 5.2 以上的版本中提供了一個npx命令

npx 想要解決的主要問題母债,就是調(diào)用項目內(nèi)部安裝的模塊暇昂,原理就是在node_modules下的.bin 目錄中找到對應(yīng)的命令執(zhí)行

使用webpack命令:npx webpack

webpack4.0之后可以實現(xiàn)0配置打包構(gòu)建舶得,0配置的特點就是限制較多掰烟,無法自定義很多配置,默認打包./src/index.js文件,默認打包到./dist文件夾下

開發(fā)中常用的還是使用webpack配置進行打包構(gòu)建

②.webpack配置

webpack有四大核心概念:

  • 入口(entry): 程序的入口js

  • 輸出(output): 打包后存放的位置

  • loader: 用于對模塊的源代碼進行轉(zhuǎn)換

  • 插件(plugins): 插件目的在于解決 loader無法實現(xiàn)的其他事

  1. 配置webpack.config.js

  2. 運行npx webpack會自動加載當(dāng)前目錄內(nèi)的webpack.config.js文件,或者可以在package.json文件的script腳本內(nèi)配置"build":"webpack":然后使用npm run build即可打包

    1. 按照指定文件打包的話需要配置webpack --config xxx.config.js
const path = require('path')

module.exports = {
  // 入口文件配置
  entry: './src/index.js',
  // 出口文件配置項
  output: {
    // 輸出的路徑纫骑,webpack2起就規(guī)定必須是絕對路徑
    path: path.join(__dirname, 'dist'),
    // 輸出文件名字
    filename: 'bundle.js'
  },
  mode: 'development' // 默認為production, 可以手動設(shè)置為development, 區(qū)別就是是否進行壓縮混淆
}

③.開發(fā)時自動編譯工具

每次要編譯代碼時蝎亚,手動運行 npm run build 就會變得很麻煩。

webpack 中有幾個不同的選項先馆,可以幫助你在代碼發(fā)生變化后自動編譯代碼:

  1. webpack's Watch Mode

  2. webpack-dev-server

  3. webpack-dev-middleware

watch

webpack指令后面加上--watch參數(shù)即可

主要的作用就是監(jiān)視本地項目文件的變化, 發(fā)現(xiàn)有修改的代碼會自動編譯打包, 生成輸出文件

  1. 配置package.json的scripts"watch": "webpack --watch"

  2. 運行npm run watch

以上是cli的方式設(shè)置watch的參數(shù)

還可以通過配置文件對watch的參數(shù)進行修改:

const path = require('path')

// webpack的配置文件遵循著CommonJS規(guī)范
module.exports = {
  entry: './src/main.js',
  output: {
    // path.resolve() : 解析當(dāng)前相對路徑的絕對路徑
    // path: path.resolve('./dist/'),
    path: path.join(__dirname, './dist/'),
    filename: 'bundle.js'
  },
  mode: 'development',
  watch: true
}

運行npm run build

webpack-dev-server (推薦)

  1. 安裝devServer

    devServer需要依賴webpack发框,必須在項目依賴中安裝webpack

    npm i webpack-dev-server webpack -D

  2. index.html中修改 <script src="/bundle.js"></script>

  3. 運行:npx webpack-dev-server

  4. 運行:npx webpack-dev-server --hot --open --port 8090

  5. 配置package.json的scripts:"dev": "webpack-dev-server --hot --open --port 8090"

  6. 運行npm run dev

devServer會在內(nèi)存中生成一個打包好的bundle.js,專供開發(fā)時使用煤墙,打包效率高梅惯,修改代碼后會自動重新打包以及刷新瀏覽器,用戶體驗非常好

以上是cli的方式設(shè)置devServer的參數(shù)

還可以通過配置文件對devServer的參數(shù)進行修改:

  1. 修改webpack.config.js
const path = require('path')

module.exports = {
  // 入口文件配置
  entry: './src/index.js',
  // 出口文件配置項
  output: {
    // 輸出的路徑仿野,webpack2起就規(guī)定必須是絕對路徑
    path: path.join(__dirname, 'dist'),
    // 輸出文件名字
    filename: 'bundle.js'
  },
  devServer: {
    port: 8090,
    open: true,
    hot: true
  },
  mode: 'development'
}
  1. 修改package.json的scripts: "dev": "webpack-dev-server"
  2. 運行npm run dev

html插件

  1. 安裝html-webpack-plugin插件npm i html-webpack-plugin -D
  2. webpack.config.js中的plugins節(jié)點下配置
const HtmlWebpackPlugin = require('html-webpack-plugin')

plugins: [
    new HtmlWebpackPlugin({
        filename: 'index.html',
        template: 'template.html'//根據(jù)模板生產(chǎn)铣减,可以不用
    })
]
  1. devServer時根據(jù)模板在express項目根目錄下生成html文件(類似于devServer生成內(nèi)存中的bundle.js)
  2. devServer時自動引入bundle.js
  3. 打包時會自動生成index.html,或者根據(jù)模板生成html

小結(jié)

只有在開發(fā)時才需要使用自動編譯工具, 例如: webpack-dev-server
項目上線時都會直接使用webpack進行打包構(gòu)建, 不需要使用這些自動編譯工具
自動編譯工具只是為了提高開發(fā)體驗

3.webpack的loader處理非js文件

①.webpack處理css文件

  1. 配置webpack.config.js
  module: {
    rules: [
      // 配置的是用來解析.css文件的loader(style-loader和css-loader)
      {
        // 用正則匹配當(dāng)前訪問的文件的后綴名是  .css
        test: /\.css$/,
        use: ['style-loader', 'css-loader'] // webpack底層調(diào)用這些包的順序是從右到左脚作,從下到上
      }
    ]
  }

loader的釋義:

  1. css-loader: 解析css文件
  2. style-loader: 將解析出來的結(jié)果 放到html中, 使其生效

②.webpack處理less文件

  1. 安裝npm i less less-loader -D
  2. rules中加入{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }

③.webpack處理sass文件

  1. 安裝npm i sass-loader node-sass -D
  2. rules中加入{ test: /\.s[ac]ss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }

④.處理圖片文件

  1. 安裝npm i file-loader url-loader -D
    url-loader封裝了file-loader, 所以使用url-loader時需要安裝file-loader
  2. 在rules規(guī)則中加入以下規(guī)則:
{
    test: /\.(png|jpg|gif)/,
    use: [{
        loader: 'url-loader',
        options: {
            // limit表示如果圖片大于5KB葫哗,就以路徑形式展示,小于的話就用base64格式展示
            limit: 5 * 1024,
            // 打包輸出目錄
            outputPath: 'images',
            // 打包輸出圖片名稱
            name: '[name]-[hash:4].[ext]'
        }
    }]
}

⑤.處理字體圖標文件

  1. npm i bootstarp@3 -S安裝bootstrap3.x 版本的
  2. 建立index.html給html-webpack-plugin添加一個模板,指定這個index.html的文件位置
  3. 在index.js中引入bootstrap的css樣式文件import "bootstrap/dist/css/bootstrap.css"
  4. 在index.html中使用bootstrap的字體圖標球涛,報錯
  5. 安裝npm i file-loader url-loader -D
  6. 在rules中加入以下規(guī)則 {test:/\.(woff|woff2|eot|svg|ttf)$/, use:'url-loader'}

4.webpack的babel轉(zhuǎn)換js語法

①.將ES6的語法轉(zhuǎn)為ES5的語法

  1. npm i babel-loader @babel/core @babel/preset-env webpack -D
{
    test:/\.js$/,
    use:{
        loader:"babel-loader",
        options:{
            presets:["@babel/env"],  
        }
    }
}

②.支持更高級的ES語法, 需要繼續(xù)安裝插件:

  • 比如使用類的靜態(tài)屬性:
class Peopel{
    //這個語法babel默認不支持劣针,如果需要支持還要下載插件,報錯提示
    static name = "李四" 
    constructor(name,age){
        this.age = age
        this.name = name
    }
}
p = new Peopel("戰(zhàn)三",12)
console.log(p.name)

1.npm i @babel/plugin-proposal-class-properties -D

{
  test: /\.js$/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: ['@babel/env'],
      plugins: ['@babel/plugin-proposal-class-properties']
    }
  },
  exclude: /node_modules/
}
  • 使用generator函數(shù)
function *fn(){
    yield 1
    yield 2
    return 3
}
var newFn = fn()
console.log( newFn.next() )
console.log( newFn.next() )
console.log( newFn.next() )
console.log( newFn.next() )
// 打包后運行報錯亿扁,新版本游覽器原本支持使用generator函數(shù)酿秸,但是使用webpack就會報錯

regeneratorRuntime is not defined

如果需要使用generator,無法直接使用babel進行轉(zhuǎn)換魏烫,因為會將generator轉(zhuǎn)換為一個regeneratorRuntime辣苏,然后使用markwrap來實現(xiàn)generator但由于babel并沒有內(nèi)置regeneratorRuntime,所以無法直接使用

需要安裝插件:npm i @babel/plugin-transform-runtime -D 同時還需安裝運行時依賴:npm install --save @babel/runtime 配置文件的時候不要忘了exclude: /node_modules/哄褒,否則報錯 babel插件鏈接

"plugins": [
 "@babel/plugin-proposal-class-properties",
 "@babel/plugin-transform-runtime"
 ]

官方更建議的做法是在項目根目錄下新建一個.babelrc的babel配置文件稀蟋,在.babelrc中添加插件,它是json格式的文件:

{
 "presets": [
 "@babel/env"
 ],
 "plugins": [
 "@babel/plugin-proposal-class-properties",
 "@babel/plugin-transform-runtime"
 ]
}
  • 使用ES6/7中對象原型提供的新方法 babel默認情況無法轉(zhuǎn)換,即使用了transform-runtime的插件也不支持轉(zhuǎn)換原型上的方法
//js是一門動態(tài)語言呐赡,在代碼執(zhí)行時可以隨時為對象添加屬性和方法退客,babel在看到對象調(diào)用方法的時候默認不會進行轉(zhuǎn)換,include這樣的新方法默認不會轉(zhuǎn)換
var str = "gao"
console.log( str.includes('a') )

需要使用另一個模塊:npm i @babel/polyfill -S
該模塊需要在使用新方法的地方直接引入:import '@babel/polyfill'

source map的使用

devtool

此選項控制是否生成链嘀,以及如何生成 source map萌狂。使用source map得啟用瀏覽器的source map設(shè)置

使用 SourceMapDevToolPlugin 進行更細粒度的配置。查看 source-map-loader 來處理已有的 source map怀泊。

選擇一種 source map 格式來增強調(diào)試過程茫藏。不同的值會明顯影響到構(gòu)建(build)和重新構(gòu)建(rebuild)的速度。

可以直接使用 SourceMapDevToolPlugin/EvalSourceMapDevToolPlugin 來替代使用 devtool 選項霹琼,它有更多的選項务傲,但是切勿同時使用 devtool 選項和 SourceMapDevToolPlugin/EvalSourceMapDevToolPlugin 插件凉当。因為devtool 選項在內(nèi)部添加過這些插件,所以會應(yīng)用兩次插件售葡。

devtool 構(gòu)建速度 重新構(gòu)建速度 生產(chǎn)環(huán)境 品質(zhì)(quality)
(none) +++ +++ yes 打包后的代碼
eval +++ +++ no 生成后的代碼
cheap-eval-source-map + ++ no 轉(zhuǎn)換過的代碼(僅限行)
cheap-module-eval-source-map o ++ no 原始源代碼(僅限行)
eval-source-map -- + no 原始源代碼
cheap-source-map + o no 轉(zhuǎn)換過的代碼(僅限行)
cheap-module-source-map o - no 原始源代碼(僅限行)
inline-cheap-source-map + o no 轉(zhuǎn)換過的代碼(僅限行)
inline-cheap-module-source-map o - no 原始源代碼(僅限行)
source-map -- -- yes 原始源代碼
inline-source-map -- -- no 原始源代碼
hidden-source-map -- -- yes 原始源代碼
nosources-source-map -- -- yes 無源代碼內(nèi)容

這么多模式用哪個好看杭?

開發(fā)環(huán)境推薦:

? cheap-module-eval-source-map

生產(chǎn)環(huán)境推薦:

? none(不使用source map)

原因如下:

  1. 使用 cheap 模式可以大幅提高 soure map 生成的效率。大部分情況我們調(diào)試并不關(guān)心列信息挟伙,而且就算 source map 沒有列楼雹,有些瀏覽器引擎(例如 v8) 也會給出列信息。
  2. 使用 module 可支持 babel 這種預(yù)編譯工具尖阔,映射轉(zhuǎn)換前的代碼烘豹。
  3. 使用 eval 方式可大幅提高持續(xù)構(gòu)建效率。官方文檔提供的速度對比表格可以看到 eval 模式的重新構(gòu)建速度都很快诺祸。
  4. 使用 eval-source-map 模式可以減少網(wǎng)絡(luò)請求携悯。這種模式開啟 DataUrl 本身包含完整 sourcemap 信息,并不需要像 sourceURL 那樣筷笨,瀏覽器需要發(fā)送一個完整請求去獲取 sourcemap 文件憔鬼,這會略微提高點效率。而生產(chǎn)環(huán)境中則不宜用 eval胃夏,這樣會讓文件變得極大轴或。

這么多模式用哪個好?

開發(fā)環(huán)境推薦:

? cheap-module-eval-source-map

生產(chǎn)環(huán)境推薦:

? none(不使用source map)

原因如下:

  1. 使用 cheap 模式可以大幅提高 soure map 生成的效率仰禀。大部分情況我們調(diào)試并不關(guān)心列信息照雁,而且就算 source map 沒有列,有些瀏覽器引擎(例如 v8) 也會給出列信息答恶。
  2. 使用 module 可支持 babel 這種預(yù)編譯工具饺蚊,映射轉(zhuǎn)換前的代碼
  3. 使用 eval 方式可大幅提高持續(xù)構(gòu)建效率悬嗓。官方文檔提供的速度對比表格可以看到 eval 模式的重新構(gòu)建速度都很快污呼。
  4. 使用 eval-source-map 模式可以減少網(wǎng)絡(luò)請求。這種模式開啟 DataUrl 本身包含完整 sourcemap 信息包竹,并不需要像 sourceURL 那樣燕酷,瀏覽器需要發(fā)送一個完整請求去獲取 sourcemap 文件,這會略微提高點效率周瞎。而生產(chǎn)環(huán)境中則不宜用 eval苗缩,這樣會讓文件變得極大。

插件

①.clean-webpack-plugin插件

該插件在npm run build時自動清除dist目錄后重新生成声诸,防止緩存等等

  1. 安裝插件

    npm i clean-webpack-plugin -D

  2. 引入插件

    const { CleanWebpackPlugin } = require('clean-webpack-plugin')
    
  3. 使用插件, 在plugins中直接創(chuàng)建對象即可

    plugins: [
        new HtmlWebpackPlugin({
          filename: 'index.html',
          template: './src/index.html'
        }),
        new CleanWebpackPlugin()
      ],
    

②.copy-webpack-plugin插件

  1. 安裝插件

    npm i copy-webpack-plugin -D

  2. 引入插件

    const CopyWebpackPlugin = require('copy-webpack-plugin')
    
  3. 使用插件, 在plugins中插件對象并配置源和目標

  4. from: 源, 從哪里拷貝, 可以是相對路徑或絕對路徑, 推薦絕對路徑

    to: 目標, 拷貝到哪里去, 相對于output的路徑, 同樣可以相對路徑或絕對路徑, 但更推薦相對路徑(直接算相對dist目錄即可)

    plugins: [
        new HtmlWebpackPlugin({
          filename: 'index.html',
          template: './src/index.html'
        }),
        new CleanWebpackPlugin(),
        new CopyWebpackPlugin([
          {
            from: path.join(__dirname, 'assets'),
            to: 'assets'
          }
        ])
      ],
    

③.BannerPlugin插件

這是一個webpack的內(nèi)置插件酱讶,用于給打包的JS文件加上版權(quán)注釋信息

  1. 引入webpack

    const webpack = require('webpack')
    
  2. 創(chuàng)建插件對象

plugins: [
    new HtmlWebpackPlugin({
        filename: 'index.html',
        template: './src/index.html'
    }),
    new CleanWebpackPlugin(),
    new CopyWebpackPlugin([
        {
            from: path.join(__dirname, 'assets'),
            to: 'assets'
        }
    ]),
    new webpack.BannerPlugin('GaoChao')
],
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市双絮,隨后出現(xiàn)的幾起案子浴麻,更是在濱河造成了極大的恐慌,老刑警劉巖囤攀,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件软免,死亡現(xiàn)場離奇詭異,居然都是意外死亡焚挠,警方通過查閱死者的電腦和手機膏萧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝌衔,“玉大人榛泛,你說我怎么就攤上這事∝澹” “怎么了曹锨?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長剃允。 經(jīng)常有香客問我沛简,道長,這世上最難降的妖魔是什么斥废? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任椒楣,我火速辦了婚禮,結(jié)果婚禮上牡肉,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好纹安,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布幅恋。 她就那樣靜靜地躺著,像睡著了一般饲窿。 火紅的嫁衣襯著肌膚如雪拧抖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天免绿,我揣著相機與錄音唧席,去河邊找鬼。 笑死嘲驾,一個胖子當(dāng)著我的面吹牛淌哟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辽故,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼徒仓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了誊垢?” 一聲冷哼從身側(cè)響起掉弛,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤症见,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后殃饿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谋作,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年乎芳,在試婚紗的時候發(fā)現(xiàn)自己被綠了遵蚜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡奈惑,死狀恐怖吭净,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情肴甸,我是刑警寧澤寂殉,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站原在,受9級特大地震影響不撑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜晤斩,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一焕檬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧澳泵,春花似錦实愚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至维苔,卻和暖如春碰辅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背介时。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工没宾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沸柔。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓循衰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親褐澎。 傳聞我的和親對象是個殘疾皇子会钝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 模塊化 CommonJS CommonJS是一種使用廣泛的 JavaScript模塊化規(guī)范,核心思想是通過 req...
    小小的白菜閱讀 586評論 0 12
  • 深入淺出Webpack學(xué)習(xí)筆記 基本概念 常用的構(gòu)建工具 所有的構(gòu)建工具所做的工做大致一樣工三,都是把源代碼翻譯轉(zhuǎn)換成...
    IsaacHHH閱讀 505評論 0 0
  • 入門介紹 為什么選擇webpack 大多數(shù)團隊在開發(fā)新項目時會采用緊跟時代的技術(shù)迁酸,這些技術(shù)幾乎都會采用“ 模塊化+...
    一米陽光kk閱讀 2,316評論 0 9
  • 引言 該SeekBar由自定義view來實現(xiàn)先鱼,主要完成了普通的進度條(可修改進度條的顏色,游標顏色奸鬓,二級進度條顏色...
    只有一條尾巴的貓閱讀 1,524評論 0 2
  • 過完吃了可以睡焙畔,睡醒了可以玩的開心年。又得背上行李全蝶,拉著皮箱闹蒜,去外地工作寺枉。其實我真不喜歡那個狀態(tài)抑淫,早上很早就去上班...
    無衣師尹_a5c9閱讀 113評論 0 0