<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                在現代前端項目的交付工作流中,部署前最關鍵的環節就是構建,構建環節要完成的事情通常包括: * 源代碼預編譯:比如 less、sass、typescript; * 圖片優化、雪碧圖生成; * JS、CSS 合并、壓縮; * 靜態資源加版本號和引用替換; * 靜態資源傳 CDN 等。 現在大多數同學所接觸的項目構建過程可能都是別人配置好的,但是對于構建過程中的某些考量可能并不是很清楚。 接下來,我們將組合 npm script 和簡單的命令行工具為實際項目添加構建過程,以加深對構建過程的理解,同時也會用到前面很多章節的知識點。 ## 項目目錄結構 對之前的示例項目做簡單改造,讓目錄結構包括典型的前端項目資源引用情況: ``` client ├── images │?? └── schedule.png ├── index.html ├── scripts │?? └── main.js └── styles └── main.css ``` 可能的資源依賴關系如下: * css、html 文件中引用了圖片; * html 文件中引用了 css、js; 顯而易見,我們的構建過程必須遵循下面的步驟才能不出錯: 1. 壓縮圖片; 2. 編譯 less、壓縮 css; 3. 編譯、壓縮 js; 4. 給圖片加版本號并替換 js、css 中的引用; 5. 給 js、css 加版本號并替換 html 中的引用; ## 添加構建過程 下面介紹如何結合 npm script 正確的給這樣的項目結構加上構建過程。 ### 1\. 準備構建目錄 我們約定構建產生的結果代碼,放在 dist 目錄下,與 client 的結構完全相同,每次構建前,清空之前的構建目錄,利用 npm 的鉤子機制添加 prebuild 命令如下: ``` - "client:static-server": "http-server client/" + "client:static-server": "http-server client/", + "prebuild": "rm -rf dist && mkdir -p dist/{images,styles,scripts}", ``` ### 2\. 準備腳本目錄 構建過程需要的命令稍長,我們可以使用 scripty 來把這些腳本剝離到單獨的文件中,為此需要準備單獨的目錄,并且我們的構建過程分為:images、styles、scripts、hash 四個步驟,每個步驟準備單獨的文件。 ``` mkdir scripts/build touch scripts/build.sh touch scripts/build/{images,styles,scripts}.sh chmod -R a+x scripts ``` **腳本文件的可執行權限必須添加正確,否則 scripty 會直接報錯**,上面命令執行完之后,scripts 目錄包含如下內容: ``` scripts ├── build │?? ├── hash.sh │?? ├── images.sh │?? ├── scripts.sh │?? └── styles.sh ├── build.sh ``` ### 3\. 圖片構建過程 圖片構建的經典工具是 [imagemin](https://github.com/imagemin/imagemin),它也提供了命令行版本 [imagemin-cli](https://github.com/imagemin/imagemin-cli),首先安裝依賴: ``` npm i imagemin-cli -D # npm install imagemin-cli --save-dev # yarn add imagemin-cli -D ``` 然后在 scripts/build/images.sh 中添加如下內容: ``` imagemin client/images/* --out-dir=dist/images ``` 然后在 package.json 中添加 build:images 命令: ``` + "build:images": "scripty", ``` 嘗試運行 npm run prebuild && npm run build:images,然后觀察 dist 目錄的變化。 ### 4\. 樣式構建過程 我們使用 [less](http://lesscss.org/usage/) 編寫樣式,所以需要預編譯樣式代碼,可以使用 less 官方庫自帶的命令行工具 lessc,使用 sass 的同學可以直接使用 [node-sass](https://github.com/sass/node-sass)。此外,樣式預編譯完成之后,我們需要使用 [cssmin](https://www.npmjs.com/package/cssmin) 來完成代碼預壓縮。首先安裝依賴: ``` npm i cssmin -D # npm install cssmin --save-dev # yarn add cssmin -D ``` 然后在 scripts/build/styles.sh 中添加如下內容,這里我們使用到了 shell 里面的管道操作符 `|` 和輸出重定向 `>`: ``` for file in client/styles/*.css do lessc $file | cssmin > dist/styles/$(basename $file) done ``` 然后在 package.json 中添加 build:styles 命令: ``` + "build:styles": "scripty", ``` 嘗試運行 npm run prebuild && npm run build:styles,然后觀察 dist 目錄的變化,應該能看到 less 編譯之后再被壓縮的 css 代碼。 ### 4\. JS 構建過程 我們使用 ES6 編寫 JS 代碼,所以需要 [uglify-es](https://github.com/mishoo/UglifyJS2/tree/harmony) 來進行代碼壓縮,如果你不使用 ES6,可以直接使用 [uglify-js](https://github.com/mishoo/UglifyJS2) 來壓縮代碼,首先安裝依賴: ``` npm i uglify-es -D # npm install uglify-es --save-dev # yarn add uglify-es -D ``` 然后在 scripts/build/scripts.sh 中添加如下內容,**需要額外注意的是,這里我們需要手動指定 uglify-es 目錄下的 bin 文件,否則識別不了 ES6 語法**,因為 uglify-es 在 npm install 過程自動創建的軟鏈是錯誤的。 ``` for file in client/scripts/*.js do ./node_modules/uglify-es/bin/uglifyjs $file --mangle > dist/scripts/$(basename $file) done ``` 然后在 package.json 中添加 build:scripts 命令: ``` + "build:scripts": "scripty", ``` 嘗試運行 npm run prebuild && npm run build:scripts,然后觀察 dist 目錄的變化,應該能看到被 uglify-es 壓縮后的代碼。 > **TIP#19**:uglify-es 支持很多其他的選項,以及 sourcemap,對 JS 代碼做極致的優化,詳細[參考](https://github.com/mishoo/UglifyJS2/tree/harmony#command-line-options) ### 4\. 資源版本號和引用替換 給靜態資源加版本號的原因是線上環境的靜態資源通常都放在 CDN 上,或者設置了很長時間的緩存,或者兩者兼有,如果資源更新了但沒有更新版本號,瀏覽器端是拿不到最新內容的,手動加版本號的過程很繁瑣并且容易出錯,為此自動化這個過程就顯得非常有價值,通常的做法是利用文件內容做哈希,比如 md5,然后以這個哈希值作為版本號,版本號附著在文件名里面,線上環境的資源引用全部是帶版本號的。 為了實現這個過程,我們需要引入兩個小工具: * [hashmark](https://github.com/keithamus/hashmark),自動添加版本號; * [replaceinfiles](https://github.com/songkick/replaceinfiles),自動完成引用替換,它需要將版本號過程的輸出作為輸入; 首先安裝依賴: ``` npm i hashmark replaceinfiles -D # npm install hashmark replaceinfiles --save-dev # yarn add hashmark replaceinfiles -D ``` 然后在 scripts/build/hash.sh 中添加如下內容: ``` # 給圖片資源加上版本號,并且替換引用 hashmark -c dist -r -l 8 '**/*.{png,jpg}' '{dir}/{name}.{hash}{ext}' | replaceinfiles -S -s 'dist/**/*.css' -d '{dir}/{base}' # 給 js、css 資源加上版本號,并且替換引用 hashmark -c dist -r -l 8 '**/*.{css,js}' '{dir}/{name}.{hash}{ext}' | replaceinfiles -S -s 'client/index.html' -d 'dist/index.html' ``` 然后在 package.json 中添加 build:hash 命令: ``` + "build:hash": "scripty", ``` 這個步驟需要依賴前幾個步驟,不能單獨運行,接下來我們需要增加完整的 build 命令把上面幾個步驟串起來。 ### 5\. 完整的構建步驟 最后我們在 package.json 中添加 build 命令把所有的步驟串起來,完整的 diff 如下: ``` - "client:static-server": "http-server client/" + "client:static-server": "http-server client/", + "prebuild": "rm -rf dist && mkdir -p dist/{images,styles,scripts}", + "build": "scripty", + "build:images": "scripty", + "build:scripts": "scripty", + "build:styles": "scripty", + "build:hash": "scripty" ``` 其中 scripts/build.sh 的內容如下: ``` for step in 'images' 'scripts' 'styles' 'hash' do npm run build:$step done ``` 然后我們嘗試運行 npm run build,完整的過程輸出如下: ![](https://img.kancloud.cn/8b/70/8b70759afe9bd712f4988e8e51c66fa3_984x1290.gif) 構建完成的 dist 目錄內容如下: ![](https://img.kancloud.cn/f0/07/f007e79b8c03d0dad360c7c87d3aad88_698x240.gif) 可以看到,所有的靜態資源都加上了版本號。 構建完成的 dist/index.html 內容如下: ![](https://img.kancloud.cn/22/43/2243aad619ba1c3e5e0499ccb203e360_875x416.gif) 可以看到,靜態資源的版本號被正確替換了,為了驗證構建出來的頁面是否正常運行,可以運行 `./node_modules/.bin/http-server dist`,然后瀏覽器打開:`http://127.0.0.1:8080`,不出意外的話,瀏覽器顯示如下: ![](https://img.kancloud.cn/fe/6d/fe6d97a252dc6d8b7b649e173b135176_865x688.gif) > **好了,到這里,我們給簡單但是五臟俱全的前端項目加上了構建過程,這些環節你是否都清楚?你覺得還缺失些什么環節?歡迎留言交流** * * * > 本節用到的代碼見 [GitHub](https://github.com/wangshijun/automated-workflow-with-npm-script/tree/12-use-npm-script-as-build-pipeline),想邊看邊動手練習的同學可以拉下來自己改,注意切換到正確的分支 `12-use-npm-script-as-build-pipeline`。 * * *
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看