不幸的是,我現在沒有時間/熱情來維護這個專案。我建議分叉這個項目,或者閱讀它的源代碼以了解它是如何構建的。
此 webpack 樣板適用於希望快速創建靜態網站的初學者、中級和高級開發人員,同時實現所有正確的優化,以在 Google Page Speed Insights 和 Google Lighthouse Reports 上獲得完美成績- 這是tris-gulp-boilerplate 的演變,現在帶有Webpack 4。值得慶幸的是,Webpack 既可以運行任務,也可以捆綁 js?
此項目/樣板的目標是涵蓋以下人群:
初學者? ——儘管使用 Gulp/Webpack/Node/Npm 仍然需要比更熟悉的開發人員更徹底的解釋。他們希望事情能夠順利進行,但他們也想知道如何以及為什麼。
業餘專案騙子?他們需要將自己的想法、應用程式和網站快速地傳送到瀏覽器中。
強迫症♂️-那些喜歡在性能和優化報告上獲得完美分數的人。以數位方式組織的人們並自豪地知道他們的所有文件都已最小化、壓縮、壓縮並準備好發送!
請隨意分叉此存儲庫並基於此模板創建您自己的工作流程!每個人都有點不同,我懂。
運行之前,您的電腦上需要有 git 和 node.js。
git clone https://github.com/tr1s/tris-webpack-boilerplate.git your-project-name
cd your-project-name && rm -rf .git
npm install
npm start
一切就緒,開始編碼吧?
如果您想要 100% 全新開始和/或建立自己的 Sass 工作流程,請刪除src/styles/
資料夾、 src/index.html
和src/index.scss/
中的所有內容。我的資料夾結構是基於 7-1 模式。
當您準備好將網站上傳到您選擇的 FTP/託管平台時,請npm run build
。這將建立一個dist
資料夾,其中包含優化和壓縮的所有網站資源。
如果您想深入了解一切如何運作,請閱讀以下功能。否則,繼續編碼並享受樂趣:)
tris-webpack-樣板
用法
特點/內容
特性解釋
Webpack 設定拆分
Webpack 開發伺服器
HTML 資源與縮小
404頁面未找到
SCSS 到 CSS + 優化
ES6 轉譯
瀏覽器列表
圖片資源+壓縮
字體加載+預加載
資產壓縮
乾淨的 Webpack 插件
原始圖
網站圖示生成
先離線再緩存
漸進式網頁應用程式 (PWA)
陷阱的
貢獻
我們不會使用一個大的webpack.config.js
,而是將生產和開發版本分割成兩個新的配置,分別稱為webpack.dev.js
和webpack.prod.js
。我們想要的開發和生產配置將位於webpack.common.js
配置中。
當我們運行npm start
時,它將基於webpack.dev.js
配置運行開發構建,該配置還具有合併的webpack.common.js
配置。在 Webpack 文件中閱讀更多相關內容。
/* wenpack.dev.js */const merge = require("webpack-merge");const common = require("./webpack.common.js");/* 合併 webpack.common.js 然後再加入你的額外*/module.exports = merge(common, { 模式:“開發”, /* 其餘程式碼放在這裡 */});
當我們運行npm run build
時,它將基於webpack.prod.js
配置運行生產構建,該配置還具有合併的webpack.common.js
配置。
/* webpack.prod.js */const merge = require("webpack-merge");const common = require("./webpack.common.js");/* 合併 webpack.common.js 然後再加入你的額外*/module.exports = merge(common, { 模式:“生產”,});
我們希望我們的開發和生產版本能夠在瀏覽器中直觀地產生相同的結果。您不想完成編碼,運行構建,然後構建一個完全不同的網站,例如缺少圖像。這就是為什麼我們有webpack.common.js
來處理所有載入器和資產管理。 webpack.dev.js
與輕量級來源映射略有不同。最後, webpack.prod.js
將處理將網站投入生產的所有最後階段。即影像壓縮、資產壓縮 (gzip)、資產縮小、圖示生成、快取以及建立離線優先體驗。
我將在下面詳細介紹每個過程。
webpack-dev-server 在 package.json 中配置。 npm start
將運行伺服器並使用webpack.dev.js
配置在瀏覽器中開啟您的專案。 npm start
是npm的預設腳本,因此不需要向其新增run
。但對於建置腳本,您需要輸入npm run build
。
"scripts": { "start": "webpack-dev-server --open --config webpack.dev.js", "build": "webpack --config webpack.prod.js"},
我們使用 html-loader 將 HTML 匯出為字串並縮小輸出。這允許您在src/index.js
中匯入src/index.html
。我們可以簡單地使用載入器選項minimize: true
HTML,這就是為什麼我們將其保留在webpack.common.js
而不是將其移至webpack.prod.js
中。
/* webpack.common.js */{ 測試:/.html$/, 使用:[{loader:'html-loader',選項:{最小化:true} }]},
/* src/index.js */import "./index.html";
然後,我們使用 html-webpack-plugin 建立一個新產生的index.html
其中包含所有正確的資源導入。
template:
選項是您從中提取來源 HTML 的位置。您可以使用自己的 html 模板、車把模板或任何其他模板。
inject:
選項是您的資產將去往的地方。預設情況下,Webpack 會將捆綁的webpack-bundle.js
腳本放在 body 的底部,但這裡我將其切換到head
因為我們將使用 script-ext-html-webpack-plugin defer
腳本並將其放置在網站的頭部。這有助於提高性能。
/* webpack.common.js */const HtmlWebpackPlugin = require('html-webpack-plugin');const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");插件: [ new HtmlWebpackPlugin({標題: 'tris-webpack-boilerplate',檔名: 'index.html',範本: './src/index.html',注入: 'head' }), new HtmlWebpackPlugin({標題: 'tris-404-page',檔名: '404.html',範本: './src/404.html',注入: 'head' }), 新的 ScriptExtHtmlWebpackPlugin({defaultAttribute: 'defer' }),],
如果您要擁有一個多頁面網站,請繼續新增更多new HtmlWebpackPlugin({})
程式。使用title:
key。
Netlify 是一項出色的免費服務,可讓您管理和部署您的網站。 Netlify 會自動搜尋404.html
,並在有人嘗試開啟您網站上的損壞連結時載入該頁面。所以您無需擔心。
如果您使用其他服務,請研究如何連結您的404.html
頁面以使其處於活動狀態。如果人們訪問了損壞的鏈接,這是將他們送回到您的主頁的好方法。
為了使用 Sass/SCSS,我們需要使用一些載入器來獲得我們想要的結果。 css-loader、postcss-loader 和 sass-loader。
test:
正在使用regex(正規表示式)檢查是否有任何sass、scss 或css 文件,然後透過這三個載入器運行它們,該載入器包裝在mini-css-extract-plugin 周圍,然後為您產生一個CSS 檔案在生產中使用。
閱讀有關加載器概念的更多資訊。
/* webpack.common.js */{ 測試:/.(sa|sc|c)ss$/, use: [MiniCssExtractPlugin.loader,{ loader: 'css-loader', options: {sourceMap: true }},{ loader: 'postcss-loader', options: {sourceMap: true }},{ loader: 'sass-loader ', 選項: {sourceMap: true }} ]},
載入程式序列的第二部分是postcss-loader
,您將在其中縮小和自動添加 CSS 前綴。為此,我們在專案的根目錄中建立一個postcss.config.js
並像這樣配置它...
/* postcss.config.js */const purgecss = require("@full human/postcss-purgecss");module.exports = { 外掛程式:[require(“autoprefixer”),require(“cssnano”)({預設:“default”,}),purgecss({內容:[“./**/*.html”],關鍵影格:true ,} ), ],};
如果需要的話,請閱讀 autoprefixer 和 cssnano 以根據您的喜好進行設定。另外,請整體閱讀 postcss,因為它是您的武器庫中非常強大的工具。
Purgecss 是一個很棒的 postcss 插件,用於刪除程式碼中未使用的 css。 Purgecss 分析您的內容和 css 檔案。然後,它將文件中使用的選擇器與內容文件中的選擇器進行匹配。它會從 css 中刪除未使用的選擇器,從而產生更小的 css 檔案。
預設情況下它已準備就緒,但如果您想親自對其進行直觀測試,請取消註釋@import "../node_modules/bulma/bulma";
在index.scss
中,然後執行npm run build
並查看 dist 資料夾中產生的webpack-bundle.css
。您會注意到沒有那麼多程式碼。然後從postcss.config.js
中刪除 purgecss 並再次執行npm run build
,您會注意到 css 中有 10,000 多行程式碼來自 Bulma 框架。正如您所看到的,purgecss 非常適合刪除您在使用 Bootstrap、Foundation、Bulma 等大型框架時不使用的 CSS!
mini-css-extract-plugin 是最後一步,因為它會提取 CSS 並在輸出之前為其命名。
/* webpack.common.js */const MiniCssExtractPlugin = require("mini-css-extract-plugin");plugins: [ new MiniCssExtractPlugin({filename: 'webpack-bundle.css',chunkFilename: '[id].css' })],
所以基本上... css-loader
將從應用程式中引用的所有 css 檔案中收集 CSS 並將它們放入一個字串中。然後postcss-loader
自動前綴並縮小你的樣式,然後sass-loader
將其轉換為 JS 模組,然後mini-css-extract-plugin
將 JS 模組中的 CSS 提取到單個 CSS 文件中以供 Web 瀏覽器解析。
您可能想使用最新的 JavaScript 功能和語法,但並非所有瀏覽器都支援它們。 Babel 會為我們處理這個問題。
在這裡,我們測試所有 js 文件,但不包括node_modules
資料夾,然後透過帶有 babel-preset-env 預設的 babel-loader 來運行它。
/* webpack.common.js */{ 測試:/.js$/, 排除:/(node_modules)/, 使用:{loader:'babel-loader',選項:{預設:['@babel/preset-env']} }}
這次我們將冒險進入webpack.prod.js
檔案。當我們npm run build
時,我們的輸出 js 將被縮小並具有完整的來源映射。透過npm start
在開發模式下運行,我們仍然會有更輕的來源映射,但 js 不會被縮小。
/* webpack.prod.js */const TerserPlugin = require("terser-webpack-plugin");module.exports = merge(common, { 模式:“生產”, devtool:“來源映射”, 最佳化:{minimizer: [ new TerserPlugin({test: /.js(?.*)?$/i,parallel: true,sourceMap: true, }),], },});
閱讀簡潔文件中有關選項的更多資訊。
在這裡,我們希望有一個地方可以告訴某些工具我們想要增加對哪些瀏覽器的支援。我們使用 browserslist 以及專案根目錄中對應的.browserslistrc
檔案來實現此目的。 Autoprefixer 和 babel-present-env 將取得此檔案並根據配置應用它所需的內容。
了解您還可以傳遞到.browserslistrc
中的內容,並使用 browserl.ist 來查看您的配置將專門針對哪些瀏覽器。好吧,我想我已經說過瀏覽器夠多次了?
/* .browserslistrc */> 0.25%沒有死
首先,我們使用 regex(正規表示式)測試 jpeg、jpg、png、gif 和 svg,然後使用 file-loader,它將檔案的匯入和需求解析為 url,然後將檔案傳送到輸出目錄。因此,如果您使用<img>
元素從src/images
資料夾中取得文件,它將被匯入並傳送到指定的輸出路徑images
。如果你npm start
(運行開發)或npm run build
(運行建置),最終會變成src/images
。
/* webpack.common.js */{ 測試:/.(jpe?g|png|gif|svg)$/, use: [{loader: '檔案載入器',options: { name: '[name].[ext]', outputPath: 'images/', publicPath: 'images/'}, }]},
現在我們只想在npm run build
上最佳化我們的映像,因此我們如下編輯webpack.prod.js
。
我們再次使用正規表示式測試 jpeg、jpg、png、gif 和 svg,並套用適當的最佳化。 gifsicle
是一個無損 gif 壓縮器, pngquant
是一個有損 png 壓縮器,我們可以添加一個名為imageminMozjpeg
的額外插件來執行有損 jpg/jpeg 壓縮。一個安全的選擇是將品質設定在 75-90 之間,您應該獲得一些不錯的壓縮,而不會損失可見品質。
我建議堅持使用無損壓縮,並在添加到項目之前將圖像裁剪到正確的尺寸。只需刪除 imageminMozjpeg 和 pngquant 關鍵部分即可。
您也可以使用tinypng進行影像壓縮。
/* webpack.prod.js */const ImageminPlugin = require("imagemin-webpack-plugin").default;const imageminMozjpeg = require("imagemin-mozjpeg");外掛程式: [ new ImageminPlugin({test: /.(jpe?g|png|gif|svg)$/i,gifsicle: { // 無損gif 壓縮器optimizationLevel: 9,},pngquant: { // 有損png 壓縮器,移除預設無損quality: "75",},plugins: [ imageminMozjpeg({// 有損 jpg 壓縮器,刪除預設無損quality: "75", }),], }),];
在這裡,我們正在測試所有常見的字體擴展,並再次使用檔案載入器來解析我們的字體導入並輸出它們。
/* webpack.common.js */{ 測試:/.(woff|woff2|ttf|otf)$/, use: [{loader: '檔案載入器',options: { name: '[name].[ext]', outputPath: 'fonts/', publicPath: 'fonts/'}, }]},
在我們的src/styles/base/_typography.scss
中,我們透過@font-face
規則載入字體。 Google Webfonts Helper 也是一個出色的工具,可以輕鬆自架 Google Fonts。閱讀更多有關 CSS-tricks 的@font-face
規則的資訊。此外,也要閱讀 font-display 屬性。
預載字體始終是最佳實踐。我們將使用 preload-webpack-plugin 來實現這一點,並且您需要將其放在HtmlWebpackPlugin
之後才能正常運作。
/* webpack.common.js */new PreloadWebpackPlugin({ rel: '預先載入', as(entry) {if (/.(woff|woff2|ttf|otf)$/.test(entry)) return '字體'; }, 文件白名單:[/.(woff|woff2|ttf|otf)$/], 包括:'所有資產'}),
在這裡,我們回到webpack.prod.js
配置中,使用compression-webpack-plugin僅壓縮 html、css 和 javascript 檔案。這是為了避免壓縮生成的來源映射檔。
/* webpack.prod.js */module.exports = merge(common, { 模式:“生產”, plugins: [new CompressionPlugin({ test: /.(html|css|js)(?.*)?$/i // 只壓縮 html/css/js,跳過壓縮來源映射等}),});
Clean-webpack-plugin 只是一個簡單的 webpack 插件,用於在建立新資料夾之前刪除/清理建置資料夾。執行npm run build
或npm start
時觀察資料夾結構。您目前的dist
資料夾(如果您之前建置過)將被刪除,並且緊接著會出現一個新資料夾。
/* webpack.common.js */const CleanWebpackPlugin = require("clean-webpack-plugin");plugins: [new CleanWebpackPlugin(["dist"])];
使用來源映射對於在開發工具中偵錯程式碼至關重要。
正如您所看到的,當您在 Chrome 中npm start
並打開 devtools 然後單擊控制台時,您將看到有兩個 console.log 來自script.js
第1 行和第2 行。夾結構中輕鬆看到這一點src/scripts/script.js
。如果我們不使用 sourcemaps,那麼 devtools 會向我們顯示這些 console.logs 來自我們捆綁的webpack-bundle.js
,這不是很有幫助。
與我們的風格類似。如果您查看 devtools 中的body
元素,您會看到一些樣式是從我們的_global.scss
檔案應用的,還有一些是從我們的_typography.scss
檔案應用的,它們都位於我們的src/styles/base/
資料夾中。如果我們忽略來源映射,我們將無法知道這一點。它只會向我們顯示來自捆綁的webpack-bundle.css
樣式。
/* webpack.dev.js */module.exports = merge(common, { 模式:“開發”, devtool: "內聯來源映射",});
/* webpack.prod.js */module.exports = merge(common, { 模式:“生產”, devtool: "來源映射",});
詳細了解不同類型的來源映射,找到最適合您的專案的來源映射。另外,請閱讀 webpack 文件中的 devtool 選項。
這是一個很棒的插件,可以根據一個圖像來源生成您需要的每個圖示。在我的src/images/
資料夾中,我有一個tris-package.svg
,我將其輸入到 favicons-webpack-plugin 中。
它將產生蘋果、安卓、chrome、firefox、twitter、windows 的圖標,凡是你能想到的。它將產生各種不同尺寸的每個圖標,並將它們直接匯入它們所屬的網站頭部。 Twitter 和 windows 設為 false 但默認,所以我將它們更改為 true 只是為了覆蓋所有基礎以防萬一。
注意:這會大大增加建置時間。考慮到它在後台做了多少工作以及從長遠來看它為您節省了多少時間,這是可以理解的。如果您的npm run build
比平時多花 20 秒,請不要感到驚訝。
/* webpack.prod.js */const FaviconsWebpackPlugin = require("favicons-webpack-plugin");module.exports = merge(common, { 模式:“生產”, 外掛程式:[new FaviconsWebpackPlugin({ logo: "./src/images/favicon.svg", 圖示: {twitter: true,windows: true, },}), ],});
在這裡,我們使用離線插件插件來快取頁面載入時的所有資源。
該插件旨在為webpack專案提供離線體驗。它使用ServiceWorker和AppCache作為幕後的後備。我們只需將此插件包含在我們的webpack.prod.js
中,並將附帶的運行時包含在我們的客戶端腳本(src/index.js) 中,我們的專案將透過快取所有(或部分) webpack 輸出資源來離線準備。
注意:如果您npm run build
並將變更上傳到您的伺服器(或您保持網站更新),則您的網站將需要關閉並重新開啟才能看到變更。您無法打開它並保持刷新,您需要關閉選項卡並重新打開它以使快取失效。
/* webpack.prod.js */const OfflinePlugin = require("offline-plugin");module.exports = merge(common, { 模式:“生產”, 插件:[new OfflinePlugin()],});
漸進式 Web 應用程式 (PWA) 是像常規網頁或網站一樣加載的 Web 應用程序,但可以為用戶提供離線工作、推播通知和傳統上僅適用於本機應用程式的裝置硬體存取等功能。 PWA 將網路的靈活性與本機應用程式的體驗結合起來。
使此樣板成為 PWA 的最後一步是將強制性的 Web 應用程式清單新增至專案的根目錄並進行適當的設定!
當嘗試捆綁像 jQuery 這樣的大型函式庫時,Webpack 會遇到問題。您最終會遇到控制台錯誤,例如$ is not defined
或jQuery is not defined
。為了解決這個問題,我們讓 Webpack 將其視為外部。然後我們定義變數並透過 CDN 包含 jQuery。無論如何,大多數人都在瀏覽器上快取了 jQuery,因此這不會成為效能問題。我預設加入了externals:
config,但如果你打算使用它,你必須自己加入 jQuery cdn。
在 Webpack 文件中閱讀有關外部的更多資訊。
/* webpack.common.js */plugins: [],externals: { $: 'jquery', jquery: 'jQuery', '窗口.$': 'jquery',}
/* src/index.html */<head> <scriptdefersrc="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" ></script></head>
我盡力徹底解釋事情,但如果可以更清楚地解釋某些事情,請隨時發送帶有一些建議編輯的拉取請求。謝謝你!
希望有幫助!如果您對此感興趣,請在 Twitter 上關注我。 ?