webpack入坑之路

Hi ~ 許久沒更新的小簡書蝇闭,自從換了新工作蕴侣,日夜掉發(fā)式的瘋狂加班泊交,一個半月的時間學(xué)到了不少東西,趁熱記錄一波吧~


程序員病.png

一個月前宏浩,接到了一個需求知残,并且長期需要維護(hù)多個無關(guān)的活動頁或者場景頁,自以為簡單的我樂呵呵的接了需求比庄,心中已經(jīng)想好“用react來搭一個多頁面應(yīng)用就夠符合需求啦~”求妹,事實證明,我還是too young too simple ,sometimes naive...

自拍照.png

實際開發(fā)工作中佳窑,react多頁面應(yīng)用的腳手架GitHub上有很多制恍,自己也可以根據(jù)官方的react腳手架就可以愉快的擼起來,但是目前遇到的比較頭疼的問題是神凑,怎么讓我的react應(yīng)用代碼壓縮模塊打包净神,這個時候就很有必要好好研究下webpack的使用了。

此次分享主要是針對多頁面的webpack4打包。

So鹃唯,咱們來聊一下爱榕,什么是webpack?

官網(wǎng)webpack圖

官網(wǎng)上的webpack相信所有前端開發(fā)童鞋都見過俯渤,webpack做的事情呆细,就是將我們的js應(yīng)用的各個文件按照模塊打包成多個bundle,是一個靜態(tài)模塊的打包器八匠。

webpack做的事情,就是分析項目結(jié)構(gòu)趴酣,找到j(luò)s模塊以及一些不能直接運行的語言梨树,并將其打包成合適的格式給瀏覽器執(zhí)行。

安裝webpack

npm install webpack-cli 

了解webpack前需要知道webpack的四大核心概念岖寞,entry抡四、output、loader仗谆、plugins指巡。

Entry(入口)

entry是webpack的起點指示,告訴webpack從哪里開始入手打包任務(wù)隶垮,用來指定入口藻雪,默認(rèn)值是./src。

如果是做單頁面程序狸吞,單個入口勉耀。

//單個入口的寫法  entry: string|Array<string>
entry:{
  main:'../src/component/my.js'
}
entry:'../src/component/my.js'
//如果傳數(shù)組形式,是注入多個入口以及多個依賴文件蹋偏。

如果是做多個頁面便斥,多個入口。

//多個入口的寫法威始,所有的文件會被打包到dist文件中枢纠。
entry:{
  app:['./a.js','./b.js','./c.js']
}
//最終輸出 dist/a.js   /  dist/b.js   dist/c.js

當(dāng)webpack在解析代碼時,每遇到import或者require引入的依賴黎棠,最終會被打包在最終構(gòu)建結(jié)果中晋渺。打包的最終結(jié)果只會引入該模塊引入的依賴。

output(輸出)

打包完后輸出的位置

output: {
    filename: 'vendor.js',
    path: '/home/index'
  }

loader(加載器)

實際上webpack只能打包js文件葫掉,其他資源例如css和html是需要加載器來將資源轉(zhuǎn)化些举,加載進(jìn)來。

舉個栗子俭厚,如果項目中使用了sass的樣式語法户魏,是無法被瀏覽器所識別的,因此需要引用loader,將sass轉(zhuǎn)義成能被識別的css語法閱讀叼丑。

 {
  test: /\.scss$/,
  use: ['style-loader', 'css-loader', 'sass-loader'],
},    

在該項目中关翎,react用的是jsx的語法,同樣無法被瀏覽器所識別鸠信,需要引用babel將jsx語法轉(zhuǎn)義成正常的js運行纵寝。

module:{
  rules:[
     {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: [
              "@babel/preset-env",//可以根據(jù)配置的目標(biāo)瀏覽器或者運行環(huán)境來自動將2015+的代碼轉(zhuǎn)為es5
              "@babel/preset-react",
              { "plugins": ["@babel/plugin-proposal-class-properties"] }//這句可以在項目中使用箭頭函數(shù)
            ],
          }
        },
  ]
}

loader的職責(zé)是單一的,一個loader相當(dāng)于一個翻譯官星立,只做翻譯某種語言爽茴,需要關(guān)心輸入和輸出。
一個項目里有多個翻譯官绰垂,在調(diào)用多個 Loader 去轉(zhuǎn)換一個文件時室奏,每個 Loader 會鏈?zhǔn)降捻樞驁?zhí)行, 第一個 Loader 將會拿到需處理的原內(nèi)容劲装,上一個 Loader 處理后的結(jié)果會傳給下一個接著處理胧沫,最后的 Loader 將處理后的最終結(jié)果返回給 Webpack。

plugins(插件)

常用的插件有

  • webpack-dev-server
  • copy-webpack-plugin
  • uglifyjs-webpack-plugin
  • webpack-spritesmith
  • clean-webpack-plugin
  • html-webpack-plugin
    ...還有好多好多

webpack-dev-server
非常常見占业,用于啟動本地開發(fā)模式绒怨,本身是一個express服務(wù)器,封裝了webpack-hot-middleware谦疾,實現(xiàn)了熱更新南蹂。

devServer:{
  host:'0.0.0.0' || 'localhost',
  post:9000,//打開的端口
  open:true,//自動打開
  contentBase:path.join(_dirname,'src')//不設(shè)置的話,默認(rèn)是當(dāng)前執(zhí)行的目錄餐蔬,一般是項目根目錄碎紊,會在項目根目錄查找index.html文件。
}

copy-webpack-plugin
在webpack相中拷貝文件或文件夾的方法樊诺。

new CopyWebpackPlugin({
  from:'.....',//需要拷貝的源目標(biāo)文件
  to:'',//拷貝后存放的文件位置
})

uglifyjs-webpack-plugin
用來壓縮優(yōu)化js文件仗考,webpack4+以上的版本可使用。
webpack4之前的版本是通過webpack.optimize.commonsChuckPlugin來壓縮js

module.exports={
  optimization:{
    minimizer:true,//默認(rèn)為true词爬,效果就是壓縮js代碼
    splitChuncks:{
      chunks:'async',//'async':分割異步打包的代碼,'all':同時分割同步和異步代碼
      cacheGroups:{//默認(rèn)的規(guī)則不會打包秃嗜,需要單獨定義
        vendors:{
          test:/[\\/]node_modules[\\/]/,
          name:'vendors'
        },
        commons:{
          test:/commons\.js/,
          name:'commons'
        }
      }
      
    }  
  }  
}

webpack-spritesmith
把零散的小圖生成一張雪碧圖,減少http請求

new SpritesmithPlugin({
      // 目標(biāo)小圖標(biāo)
      src: {
        cwd: `src/assets/images/sprites`,
        glob: '*.png'
      },
      // 輸出雪碧圖文件及樣式文件7
      target: {
        image: `dist/static/images/sprite-[hash].png`,
        css: [
          [
            `dist/static/css/sprite.css`, {
              formatOpts: {
                cssSelector: (groupName) => `.icon-${groupName.name}` // 修改生成的sprite css中類名定義
              }
            }
          ]
        ]
      },
      // 樣式文件中調(diào)用雪碧圖地址寫法
      apiOptions: {
        cssImageRef: '../images/sprite-[hash].png'
      },
      spritesmithOptions: {
        algorithm: 'top-down'
      }
    })

clean-webpack-plugin
用來清除文件

// 刪除文件 保留新文件
new CleanWebpackPlugin(['dist']),

html-webpack-plugin
為入口文件html加載js依賴顿膨,動態(tài)添加編譯后的hash值文件锅锨,防止引用緩存文件的問題。

const HtmlWebpackPlugin = require('html-webpack-plugin')
  plugins: [
    new HtmlWebpackPlugin({ // 打包輸出HTML
      minify: { // 壓縮HTML文件
        removeComments: true, // 移除HTML中的注釋
        collapseWhitespace: true, // 刪除空白符與換行符
        minifyCSS: true// 壓縮內(nèi)聯(lián)css
      },
      filename: 'a.html',
      template: 'a.html'
    }),
    new HtmlWebpackPlugin({ // 打包輸出HTML
      minify: { // 壓縮HTML文件
        removeComments: true, // 移除HTML中的注釋
        collapseWhitespace: true, // 刪除空白符與換行符
        minifyCSS: true// 壓縮內(nèi)聯(lián)css
      },
      filename: 'b.html',
      template: 'b.html'
    }),
  ]

項目是多頁的情況下恋沃,傳入的html入口文件設(shè)置多個即可必搞。
可以寫一個提取html的函數(shù),批量獲取囊咏,組合成數(shù)組形式恕洲。

resolve配置

webpack在啟動后會從配置的入口模塊出發(fā)去找尋所有依賴的模塊塔橡,resolve配置webpack如何找尋模塊所對應(yīng)的文件。
alias
resolve.alias配置項通過設(shè)置其他名字來將原路徑映射成新的路徑

resolve:{
  extensions: ['.js', '.json','.css'],//導(dǎo)入的語句中如果沒帶文件后綴名霜第,webpack會自動帶上后綴名去嘗試文件是否存在葛家,用于配置在嘗試過程中用到的后綴列表。
  alias:{
    'api':utils.resolve('/src/common/api/'),//通過api關(guān)鍵字替換'/src/common/api/'
  }
}

總結(jié)

歸結(jié)webpack在實際項目中做了哪些事情泌类?
1癞谒、webpack從context設(shè)置的文件位置開始找尋
2、尋找entry里的所有文件名
3刃榨、在js文件編譯過程中弹砚,遇到 import | require 引入的依賴文件,然后在依賴文件遞歸找尋所有依賴枢希,最終打包在最終編譯生成的文件迅栅。
4、webpack把所有生成的文件都輸出到output.path路徑中晴玖,以output.filename對應(yīng)命名的模塊來命名。

webpack之所以強(qiáng)大为流,是在于插件各式各樣呕屎,總能滿足你的需求。webpack4的新api大大的提高了Code Splitting 的體驗敬察,以上講的內(nèi)容還是淺顯了點秀睛,具體的一些細(xì)節(jié)還是需要靠同志們自己愉快的擼起來,只有實操才是檢驗?zāi)芰Φ奈ㄒ煌緩絶


婊砸.png

最后莲祸,po上項目中的webpack相關(guān)依賴的版本情況

{
 "@babel/core": "^7.1.2",
    "@babel/plugin-proposal-class-properties": "^7.2.1",
    "@babel/plugin-transform-runtime": "^7.3.4",
    "@babel/preset-env": "^7.1.0",
    "@babel/preset-react": "^7.0.0",
    "@babel/runtime": "^7.3.4",
    "babel-loader": "^8.0.4",
    "babel-preset-env": "^1.7.0",
    "clean-webpack-plugin": "^2.0.0",
    "copy-webpack-plugin": "^5.0.3",
    "css-loader": "^1.0.0",
    "file-loader": "^2.0.0",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.2.0",
    "image-webpack-loader": "^5.0.0",
    "jsx-loader": "^0.13.2",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^7.1.0",
    "script-loader": "^0.7.2",
    "style-loader": "^0.23.0",
    "uglifyjs-webpack-plugin": "^2.0.1",
    "url-loader": "^1.1.2",
    "webpack": "^4.20.2",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.9",
    "webpack-spritesmith": "^0.5.4",
    "clean-webpack-plugin": "^2.0.0",
    "copy-webpack-plugin": "^5.0.3",
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蹂安,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子锐帜,更是在濱河造成了極大的恐慌田盈,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缴阎,死亡現(xiàn)場離奇詭異允瞧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蛮拔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門述暂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人建炫,你說我怎么就攤上這事畦韭。” “怎么了肛跌?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵艺配,是天一觀的道長察郁。 經(jīng)常有香客問我,道長妒挎,這世上最難降的妖魔是什么绳锅? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮酝掩,結(jié)果婚禮上鳞芙,老公的妹妹穿的比我還像新娘。我一直安慰自己期虾,他們只是感情好原朝,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著镶苞,像睡著了一般喳坠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茂蚓,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天壕鹉,我揣著相機(jī)與錄音,去河邊找鬼聋涨。 笑死晾浴,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的牍白。 我是一名探鬼主播脊凰,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼茂腥!你這毒婦竟也來了狸涌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤最岗,失蹤者是張志新(化名)和其女友劉穎帕胆,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仑性,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡惶楼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了诊杆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歼捐。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖晨汹,靈堂內(nèi)的尸體忽然破棺而出豹储,到底是詐尸還是另有隱情,我是刑警寧澤淘这,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布剥扣,位于F島的核電站巩剖,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏钠怯。R本人自食惡果不足惜佳魔,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望晦炊。 院中可真熱鬧鞠鲜,春花似錦、人聲如沸断国。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽稳衬。三九已至霞捡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間薄疚,已是汗流浹背碧信。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留街夭,地道東北人音婶。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像莱坎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子寸士,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

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