摘要:所以,打包工具就出現(xiàn)了,它可以幫助做這些繁瑣的工作。打包工具介紹僅介紹款主流的打包工具,,,,以發(fā)布時(shí)間為順序。它定位是模塊打包器,而屬于構(gòu)建工具。而且在其他的打包工具在處理非網(wǎng)頁文件比如等基本還是需要借助它來實(shí)現(xiàn)。
本文當(dāng)時(shí)寫在本地,發(fā)現(xiàn)換電腦很不是方便,在這里記錄下。
前端的打包工具打包工具可以更好的管理html,css,javascript,使用可以錦上添花,不使用也沒關(guān)系。1. 前言 1.1 前端
前端三劍客:結(jié)構(gòu)層 html,表現(xiàn)層 css,行為層 javascript。
html好比是房子的地基,css和 javascript是房子的建筑材料,這三個(gè)部分一起組成個(gè)漂亮的房子。我們不能把他們分開說,某某部分是個(gè)房子,只有三個(gè)一起才能組成一個(gè)漂亮的房子 。
1.2 JavaScript 的簡(jiǎn)介(參考阮一峰的ES6入門簡(jiǎn)介)這幾年,javascript 發(fā)展非??焖?,特別是在2015年,更是有一個(gè)質(zhì)的飛躍。
說到 JavaScript,就要說下Web標(biāo)準(zhǔn)的組織協(xié)會(huì),ECMA,它是“European Computer Manufactures Association”的縮寫,中文稱 歐洲計(jì)算機(jī)制造聯(lián)合會(huì),1961年成立,旨在建立統(tǒng)一的電腦操作格式標(biāo)準(zhǔn)--包括程序語言和輸入輸出的組織。
2015年,JavaScript 引入許多新的語法糖,而且制定過程當(dāng)中,還有很多組織和個(gè)人不斷提交新功能。事情很快就變得清楚了,不可能在一個(gè)版本里面包括所有將要引入的功能。
常規(guī)的做法是先發(fā)布 6.0 版,過一段時(shí)間再發(fā) 6.1 版,然后是 6.2 版、6.3 版等等 ,這個(gè)2015年之前 JavaScript 現(xiàn)在習(xí)慣稱為ECMAScript5,而之后稱為ECMAScript6。
標(biāo)準(zhǔn)委員會(huì)商定后最終決定,標(biāo)準(zhǔn)在每年的 6 月份正式發(fā)布一次,作為當(dāng)年的正式版本。接下來的時(shí)間,就在這個(gè)版本的基礎(chǔ)上做改動(dòng),直到下一年的 6 月份,草案就自然變成了新一年的版本。這樣一來,就不需要以前的版本號(hào)了,只要用年份標(biāo)記就可以了。
因此,ES6 既是一個(gè)歷史名詞,也是一個(gè)泛指,含義是 5.1 版以后的 JavaScript 的下一代標(biāo)準(zhǔn),涵蓋了 ES2015、ES2016、ES2017 等等,而 ES2015 則是正式名稱,特指該年發(fā)布的正式版本的語言標(biāo)準(zhǔn)。本書中提到 ES6 的地方,一般是指 ES2015 標(biāo)準(zhǔn),但有時(shí)也是泛指“下一代 JavaScript 語言”。
問題一:關(guān)于ECMAScript 和 JavaScript 是什么關(guān)系 ?
回答:從現(xiàn)在的角度來看,二者是可以互換的。即ECMAScript是JavaScript ,JavaScript 是ECMAScript。
問題二:ECMAScript 6 和 ECMAScript 2015 是什么關(guān)系 ?
回答:ECMAScript 6泛指下一代 JavaScript 語言,ECMAScript 2015指的是 2015年的 JavaScript 標(biāo)準(zhǔn);
總結(jié)
// es6 泛指下一代 JavaScript 語言,當(dāng)時(shí)部分人也會(huì)認(rèn)為特指ES2015 ECMAScript6.0 = ECMAScript2015 = es2015 = es6(部分人會(huì)這么認(rèn)為) ECMAScript6.1 = ECMAScript2016 = es2016 = es7(部分人會(huì)這么認(rèn)為) ECMAScript6.2 = ECMAScript2017 = es2017 = es8(部分人會(huì)這么認(rèn)為)
很尷尬的是,JavaScript發(fā)展很快,但是瀏覽器跟不上腳本更新的進(jìn)度。一方面給出了標(biāo)準(zhǔn),一方面卻不能直接在瀏覽器上使用。
這就出現(xiàn)了 Babel,Babel自稱是 JavaScript 編譯器,它的作用就是將ES6新語法轉(zhuǎn)成ES5,即現(xiàn)在瀏覽器可識(shí)別的腳本(基本現(xiàn)在是針對(duì)老版 IE 內(nèi)核)。
但是使用 Babel 編譯也有缺陷,那就是每一次保存,都需要手動(dòng)的使用命令行編譯,而且編譯過程中還需要相關(guān)聯(lián)的包配合使用,很繁瑣。所以,打包工具就出現(xiàn)了,它可以幫助做這些繁瑣的工作。
2. 打包工具 2.1 介紹僅介紹 4 款主流的打包工具:grunt , gulp,webpack, rollup,以發(fā)布時(shí)間為順序。
Grunt:最老牌的打包工具,它運(yùn)用配置的思想來寫打包腳本,一切皆配置,所以會(huì)出現(xiàn)比較多的配置項(xiàng),諸如option,src,dest等等。而且不同的插件可能會(huì)有自己擴(kuò)展字段,認(rèn)知成本高,運(yùn)用的時(shí)候需要明白各種插件的配置規(guī)則。
Gulp:用代碼方式來寫打包腳本,并且代碼采用流式的寫法,只抽象出了gulp.src, gulp.pipe, gulp.dest, gulp.watch 接口,運(yùn)用相當(dāng)簡(jiǎn)單。更易于學(xué)習(xí)和使用,使用gulp的代碼量能比grunt少一半左右。
Webpack: 是模塊化管理工具和打包工具。通過 loader 的轉(zhuǎn)換,任何形式的資源都可以視作模塊,比如 CommonJs 模塊、AMD 模塊、ES6 模塊、CSS、圖片等。它可以將許多松散的模塊按照依賴和規(guī)則打包成符合生產(chǎn)環(huán)境部署的前端資源。還可以將按需加載的模塊進(jìn)行代碼分隔,等到實(shí)際需要的時(shí)候再異步加載。它定位是模塊打包器,而 Gulp/Grunt 屬于構(gòu)建工具。Webpack 可以代替 Gulp/Grunt 的一些功能,但不是一個(gè)職能的工具,可以配合使用。
Rollup:下一代 ES6 模塊化工具,最大的亮點(diǎn)是利用 ES6 模塊設(shè)計(jì),利用 tree-shaking生成更簡(jiǎn)潔、更簡(jiǎn)單的代碼。一般而言,對(duì)于應(yīng)用使用 Webpack,對(duì)于類庫使用 Rollup;需要代碼拆分(Code Splitting),或者很多靜態(tài)資源需要處理,再或者構(gòu)建的項(xiàng)目需要引入很多 CommonJS 模塊的依賴時(shí),使用 webpack。代碼庫是基于 ES6 模塊,而且希望代碼能夠被其他人直接使用,使用 Rollup。
2.2 使用總結(jié)Grunt:MPA,老牌打包工具,基于文件為媒介(運(yùn)行慢,零散的腳本文件一當(dāng)多起來就受到影響
Gulp:MPA,易學(xué),基于 nodejs 的 steam 流打包
Webpack:SPA,目前最強(qiáng)大的打包工具,但是過于臃腫,如何單純打包js不推薦
Roleup:MPA,tree-shaking特性(針對(duì)es6,按需打包,多余的不要,目前(2018,vuex,react主流使用)
2.3 如何選擇如果你一個(gè)都不熟悉的話,那么我直接推薦 webpack,官方文檔非常詳細(xì),更新頻率很高。而且在其他的打包工具在處理非網(wǎng)頁文件(比如svg, png, vue等)基本還是需要借助它來實(shí)現(xiàn)。最關(guān)鍵現(xiàn)在的腳手架主流依舊是它。
如果在處理文件需要關(guān)注前端三劍客的話,那么 grunt 和 gulp 會(huì)更好點(diǎn),這兩者我直接推薦 gulp,除非你已經(jīng)很熟悉 grunt了。
如果你更加在意腳本代碼的簡(jiǎn)潔精煉,那么可以使用rollup
如果你還要更加精煉一點(diǎn),這里新出來一個(gè)新的打包工具,免插件式parcel
3. 個(gè)人打包配置在打包上,我個(gè)人注重的是配置從簡(jiǎn)單到復(fù)雜,所以我分開使用。
css 打包選擇了gulp,2個(gè)任務(wù),3個(gè)插件,有一個(gè)插件是為了編譯scss,如果直接使用css,那么這個(gè)插件也可以去除。
// 任務(wù)一:編譯 gulp.task("compile", function () { return gulp.src("src/scss/*.scss") .pipe(sass({outputStyle: "expanded"})) // 插件一:編譯scss .on("error", showError) .pipe(autoprefixer({ // 插件二:自動(dòng)添加瀏覽器前綴 browsers: ["> 1%", "last 4 versions"], cascade: false, remove: true })) .pipe(cleanCss({ // 插件三:壓縮樣式 compatibility: "ie8", format: "keep-breaks" })) .pipe(gulp.dest("../dist/css")); }) // 任務(wù)二:觀察 gulp.task("watch", function(){ gulp.watch("src/scss/*.scss", ["compile"]) })
ECMAScript 個(gè)人現(xiàn)在基本使用es6,所以在打包腳本上我選擇了rollup,只提取有用的代碼,配置上參考react官方配置文檔
import resolve from "rollup-plugin-node-resolve"; import babel from "rollup-plugin-babel"; import commonjs from "rollup-plugin-commonjs"; import { eslint } from "rollup-plugin-eslint"; import { uglify } from "rollup-plugin-uglify"; const env = process.env.NODE_ENV; console.log("當(dāng)前環(huán)境:%s", env); const configs = [ { input: "src/js/index.js", output: { file: "dist/js/index.js", format: "umd", name: "atom", banner, sourcemap: true } } ] const plugins = [ eslint({ // 檢測(cè)js代碼語法格式 formatter: "codeframe", include: [ "src/js/**/*.js" ] }), resolve({ // 提取所依賴的代碼 jsnext: true, main: true, browser: true, module: true }), babel({ // 編譯es6 -> es5 exclude: "node_modules/**" // 只編譯我們的源代碼 }), commonjs() // 將commonjs 轉(zhuǎn)成 es6 ] export default configs.map(v => { v.plugins = plugins if (env === "development") { v.watch = { // 監(jiān)聽腳本的變化 include: "src/js/**", exclude: ["node_modules/**"] } } if (env === "production") { v.plugins.push( uglify({ // 壓縮腳本 compress: { pure_getters: true, unsafe: true, unsafe_comps: true, warnings: false } }) ) } return v });
html 個(gè)人不做任何處理,可以在上線壓縮減少文件的體積,壓縮直接使用gulp
// 任務(wù)一 gulp.task("testHtmlmin", function () { var options = { removeComments: true,//清除HTML注釋 collapseWhitespace: true,//壓縮HTML collapseBooleanAttributes: true,//省略布爾屬性的值 ==> removeEmptyAttributes: true,//刪除所有空格作屬性值 ==> removeScriptTypeAttributes: true,//刪除