工程化 -- Webpack

工程化即供,簡單來說就是使小作坊生產(chǎn)變成流水線生產(chǎn)感局,實現(xiàn)自動化、模塊化琐凭、性能優(yōu)化等芽隆。

自動化可以通過命令行來實現(xiàn)。

實現(xiàn)從SCSS到CSS的自動化

  1. 全局安裝Node-sass node-sass
    npm install -g node-sass
    (事實上SASS是Ruby社區(qū)寫的)
  2. 為了演示實現(xiàn)過程统屈,我先把目錄已有的一個style.css后綴改成style.scss
    mv style.css style.scss
    這樣直接改后綴是沒有問題的胚吁,因為SCSS是完全兼容CSS的,它只是在CSS語法上加上一些更高級的用法愁憔。
  3. 現(xiàn)在可以用node-sass把SCSS翻譯成CSS了
    node-sass style.scss style.css
    實際上現(xiàn)在只是將排版變得漂亮了一點腕扶,因為我們并沒有改SCSS的內(nèi)容。
  4. 在style.scss寫一些新語法吨掌,例如:
.topNavBar{
        nav {
            padding-top: 5px;
            > ul {
                list-style: none;
                margin: 0;
                padding: 0;
                > li {
                    float: left;
                    margin-left: 17px;
                    margin-right: 17px;
                    position: relative;
                    > a {
                        font-size: 12px;
                        color: inherit;
                        font-weight: bold;
                        border-top: 3px solid transparent;
                        border-bottom: 3px solid transparent;
                        padding-top: 5px;
                        padding-bottom: 5px;
                        display: block;
                        position: relative;
                    }
                }
            }
        }
    }
  1. 再次運(yùn)行命令 node-sass style.scss style.css半抱,可以看到style.css里對應(yīng)內(nèi)容已經(jīng)被翻譯成CSS語法:
.topNavBar nav {
  padding-top: 5px; }
  .topNavBar nav > ul {
    list-style: none;
    margin: 0;
    padding: 0; }
    .topNavBar nav > ul > li {
      float: left;
      margin-left: 17px;
      margin-right: 17px;
      position: relative; }
      .topNavBar nav > ul > li > a {
        font-size: 12px;
        color: inherit;
        font-weight: bold;
        border-top: 3px solid transparent;
        border-bottom: 3px solid transparent;
        padding-top: 5px;
        padding-bottom: 5px;
        display: block;
        position: relative; }
  1. 由于不能直接引入style.scss,現(xiàn)在每次改style.scss都要執(zhí)行一次命令將其翻譯成CSS語法膜宋,這樣寫豈不是很傻窿侈?
  2. 使用-w監(jiān)聽style.scss的變動,每次style.scss有改動都自動翻譯
    node-sass style.scss style.css -w

如此就實現(xiàn)了從SCSS到CSS的自動化秋茫。

Babel自動將下一代JS代碼變成瀏覽器兼容的JS代碼

  1. 我在寫JS的時候已經(jīng)用到了很多新的語法史简,當(dāng)把代碼下發(fā)給很多用戶時,總會有不兼容的瀏覽器肛著,比如IE圆兵。我需要將使用了新語法代碼變?yōu)闉g覽器兼容的代碼
  2. Babel命令行可以實現(xiàn)這個需求。
  3. 安裝Babel
    npm install --save-dev babel-cli
    安裝之前應(yīng)該有package.json策泣,如果沒有衙傀,新建一個。
    npm init可以創(chuàng)建一個合法的package.json萨咕。
    安裝完成后檢查一下package.json统抬,如果多出下面代碼,說明已經(jīng)成功將Babel安裝到項目中了。
{
  "devDependencies": {
+   "babel-cli": "^6.0.0"
  }
}
  1. 在package.json里加代碼:(如果有上一句聪建,記得寫逗號)
 {
    "name": "my-project",
    "version": "1.0.0",
+   "scripts": {
+     "build": "babel src -d lib"
+   },
    "devDependencies": {
      "babel-cli": "^6.0.0"
    }
  }
  1. 根據(jù)文檔運(yùn)行npm run build钙畔,報錯。
    為什么呢金麸?因為運(yùn)行npm run build就是在運(yùn)行前面加的代碼babel src -d lib擎析,也就是運(yùn)行npm run build和直接運(yùn)行babel src -d lib沒有任何區(qū)別。而我們的Babel是局部安裝的挥下,安裝在./node_modules/.bin/babel揍魂,路徑?jīng)]有寫全當(dāng)然會報錯。
    運(yùn)行./node_modules/.bin/babel src -d lib相當(dāng)于第4步npm在scripts里加入的一句代碼棚瘟,反過來說现斋,當(dāng)npm運(yùn)行第4步所加的這句話的時候會優(yōu)先認(rèn)為babel是./node_modules/.bin/babel,會優(yōu)先找這個路徑偎蘸。
    命令行的實質(zhì)就是文件庄蹋,全局安裝和項目安裝的區(qū)別看這里
  2. babel src -d lib的意思是把src目錄的JS全部翻譯成兼容瀏覽器的JS,放在lib目錄里迷雪。d限书,destination。命令行基礎(chǔ)要扎實章咧,從一個字母猜到它的意思倦西。
    例如,運(yùn)行./node_modules/.bin/babel js -d dist赁严,將js目錄里的文件翻譯到dist目錄里
  3. 頁面中要引入/js的地方路徑改為/dist调限,也就是引入dist里面的js,而不是js里面的js
  4. 我們又遇到了跟上文寫SASS一樣的問題误澳,每次改寫js都要再執(zhí)行一次命令耻矮,很傻。babel也提供了跟SASS一樣的命令忆谓,讓它自動翻譯:./node_modules/.bin/babel js -d dist --watch

整理代碼

按照前端一般的規(guī)范裆装,項目里有兩個大目錄,src(source)放未經(jīng)翻譯的代碼倡缠,dist(distribution)放待發(fā)布代碼哨免。如果有第三方代碼,放在node_modules里昙沦。

把所有html琢唾,SCSS,js盾饮,包括img都放進(jìn)src中采桃。
mkdir src
mkdir src/css
mv *.html src/
mv *.scss src/css
mv js/ src/
mv img src/
現(xiàn)在src目錄中包含一個首頁懒熙、一個css目錄、一個js目錄普办、一個img目錄工扎,整齊多了。(整理完要改引入文件的路徑)
雖然整齊了衔蹲,但是現(xiàn)在代碼不能運(yùn)行了肢娘,必須要做翻譯。

進(jìn)程1:
先用node-sass將src/css/翻譯到dist/css/并監(jiān)聽舆驶,輸出到一個目錄里要用-o
node-sass src/css -o dist/css -w

進(jìn)程2:
再用Babel將src/js/翻譯到dist/js/并監(jiān)聽
./node_modules/.bin/babel src/js/ -d dist/js/ --watch

進(jìn)程3橱健,進(jìn)程4:
此外,index.html和img目錄也需要被監(jiān)聽沙廉,每次有變化就拷貝到dist目錄畴博,這又需要兩個進(jìn)程。watch-cli

以上所實現(xiàn)的自動化蓝仲,是因為前端比較分裂,有人喜歡寫css官疲,有人喜歡寫sass袱结;有人喜歡寫ES5的JS,有人喜歡寫ES6的JS途凫,等等垢夹。用翻譯工具把它們自動翻譯成兼容瀏覽器的代碼,就是自動化维费。

如果有更復(fù)雜的需求果元,比如dist發(fā)布時加版本號,一旦有需求自動改版本號犀盟,則需要開更多的進(jìn)程而晒。請看Cache-Control 如何更新緩存

這一大堆進(jìn)程可以用一個工具實現(xiàn),一開始是Grunt阅畴,后來被更快的Gulp替代倡怎,再后來又被Webpack替代。

配置Webpack

webpack github

  1. 在一個安全的目錄中演示
    mkdir webpack-demo
    cd webpack-demo
    npm init -y
    npm install webpack@3 webpack-cli --save-dev 演示webpack3
    現(xiàn)在可以看到package.json中多了一條依賴:
"devDependencies": {
    "webpack": "^3.12.0",
    "webpack-cli": "^3.0.1"
}
  1. 創(chuàng)建配置文件 touch webpack.config.js
  2. src/index.js輸出為dist/bundle.js贱枣,創(chuàng)建演示需要的目錄和文件
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};
  1. 試一下监署,在index.js里寫入
let a = 1
console.log(a)

執(zhí)行命令npx webpacknode_modules/.bin/webpack
可以看到當(dāng)前目錄里出現(xiàn)了dist/bundle.js,可以在這個文件中找到index.js里的代碼纽哥,現(xiàn)在webpack可以做簡單的JS拷貝工作了钠乏。

  1. 繼續(xù)寫配置,讓JS兼容瀏覽器春塌,讓let變成var
    babel-loader 7.x
module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['env']
        }
      }
    }
  ]
}

再次運(yùn)行npx webpack晓避,報錯簇捍,找不到什么就npm install 找不到的東西
如果是找不到envnpm install @babel/preset-env
運(yùn)行成功后够滑,dist/bundle.js中的let已經(jīng)變成var

  1. 使用模塊化
    在當(dāng)前目錄下src/js目錄里創(chuàng)建module-1.js垦写,module-2.js和app.js三個文件:
//module-1.js
function fn(){
    console.log(1)
}
export default fn  //如果有人引用module-1.js,就默認(rèn)把fn傳給他
//module-2.js
function fn(){
    console.log(2)
}
export default fn
//app.js
import x from './module-1'
import y from './module-2' //x彰触,y就是module-1梯投,module-2返回的fn

x()
y()

然后只需要把a(bǔ)pp.js翻譯成瀏覽器兼容的JS即可。更改webpack配置况毅,把src/js中的三個JS文件翻譯到dist/js/bundle.js中:

const path = require('path');

module.exports = {
  entry: './src/js/app.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist/js')
  }
};

再次運(yùn)行./node_modules/.bin/webpack分蓖,可以看到結(jié)果三個文件輸出到了一個文件中:

bundle.js  3.27 kB       0  [emitted]  main
   [0] ./src/js/app.js 343 bytes {0} [built]
   [1] ./src/js/module-1.js 141 bytes {0} [built]
   [2] ./src/js/module-2.js 141 bytes {0} [built]

頁面中只需要引入一個bundle.js就可以了。
這樣就實現(xiàn)了JS的模塊化有JS自己來控制尔许,而不是在html里面控制么鹤。

  1. sass-loader把SCSS翻譯成CSS:
    安裝sass-loader:npm install sass-loader node-sass webpack --save-dev
    安裝style-loader和css-loader:npm install style-loader css-loader --save-dev
    寫配置:
 module: {
        rules: [
        {......}, //前面已有的配置
        {
            test: /\.scss$/,
            use: [ //從下往上
                "style-loader", // 用JS字符串創(chuàng)建style節(jié)點
                "css-loader", // translates CSS into CommonJS 把css變成字符串
                "sass-loader" // 把sass編譯成css
            ]
        }]
}

模塊化:把src/css/main.scss加載到dist/js/bundle.js中變成一個字符串,等bundle.js運(yùn)行的時候把這個字符串放到頁面里的style標(biāo)簽里味廊。(css可以用字符串的形式存儲蒸甜,例如皮卡丘)

// src/js/app.js
import x from './module-1.js'
import y from './module-2.js'
import '../css/main.scss' //css也從這里引入

x()
y()
  1. 自動加前綴 postcss-loader
    安裝postcss-loader npm i -D postcss-loader
    新建postcss.config.js寫配置:touch postcss.config.js
module.exports = {
  //parser: 'sugarss',
  plugins: {
    'postcss-import': {},
    'postcss-cssnext': {},
    'cssnano': {}
  }
}

寫webpack.config.js:

 use: [
    "style-loader", 
    "css-loader", 
    "postcss-loader", //必須寫在style-loader和css-loader之后,其他之前
    "sass-loader" 
]

再運(yùn)行./node_modules/.bin/webpack余佛,看報錯柠新,找不到什么就安裝什么。

本文代碼

webpack每次需要實現(xiàn)一個功能都需要寫配置辉巡,很不方便恨憎。可以使用不需要寫配置的parcel代替它郊楣。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末憔恳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子净蚤,更是在濱河造成了極大的恐慌钥组,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件今瀑,死亡現(xiàn)場離奇詭異者铜,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)放椰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門作烟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人砾医,你說我怎么就攤上這事拿撩。” “怎么了如蚜?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵压恒,是天一觀的道長影暴。 經(jīng)常有香客問我,道長探赫,這世上最難降的妖魔是什么型宙? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮伦吠,結(jié)果婚禮上妆兑,老公的妹妹穿的比我還像新娘。我一直安慰自己毛仪,他們只是感情好搁嗓,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著箱靴,像睡著了一般腺逛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上衡怀,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天棍矛,我揣著相機(jī)與錄音,去河邊找鬼抛杨。 笑死够委,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蝶桶。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼掉冶,長吁一口氣:“原來是場噩夢啊……” “哼真竖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起厌小,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤恢共,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后璧亚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體讨韭,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年癣蟋,在試婚紗的時候發(fā)現(xiàn)自己被綠了透硝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡疯搅,死狀恐怖濒生,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情幔欧,我是刑警寧澤罪治,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布丽声,位于F島的核電站,受9級特大地震影響觉义,放射性物質(zhì)發(fā)生泄漏雁社。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一晒骇、第九天 我趴在偏房一處隱蔽的房頂上張望霉撵。 院中可真熱鬧,春花似錦厉碟、人聲如沸喊巍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崭参。三九已至,卻和暖如春款咖,著一層夾襖步出監(jiān)牢的瞬間何暮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工铐殃, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留海洼,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓富腊,卻偏偏與公主長得像坏逢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子赘被,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

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

  • 1 Webpack 1.1 概念簡介 1.1.1 WebPack是什么 1是整、一個打包工具 2、一個模塊加載工具 3...
    Kevin_Junbaozi閱讀 6,638評論 0 16
  • 版權(quán)聲明:本文為博主原創(chuàng)文章事秀,未經(jīng)博主允許不得轉(zhuǎn)載。 webpack介紹和使用 一野舶、webpack介紹 1易迹、由來 ...
    it筱竹閱讀 11,028評論 0 21
  • 代碼鏈接 概述 工程化包括了自動化 + 模塊化 + 性能優(yōu)化,前端語言較多并且更新頻率較快平道。 當(dāng)我們面對這么多語言...
    bowen_wu閱讀 641評論 0 0
  • 一赴蝇、webpack的基本概念 webpack 本質(zhì)上是一個打包工具,它會根據(jù)代碼的內(nèi)容解析模塊依賴巢掺,幫助我們把多個...
    cilla123閱讀 1,530評論 0 8
  • GitChat技術(shù)雜談 前言 本文較長句伶,為了節(jié)省你的閱讀時間劲蜻,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,671評論 7 110