摘要:一前言文章介紹了一個現代化的項目的環境是什么樣的。其中一個就是引用路徑的問題。擴展將多帶帶打包詳細介紹見這是一個插件,可以簡化創建文件以便為包提供服務。兩種環境的配置在中都支持的配置具體的默認配置查詢可以移步這里的默認設置。
一 前言
文章介紹了一個現代化的項目的webpack4環境是什么樣的。這里只是介紹了基礎的功能,如果需要詳細的相關只是可以去webpack官網去查閱。
代碼地址:github
環境特點:
1.使用了webpack-dev-middleware,在文件內容更改之后自動編譯;
2.使用了webpack-hot-middleware,在熱編譯之后會自動刷新頁面更改的內容,而不是刷新整個頁面
3.使用了server.js文件來自己控制啟動http服務,后期可以擴展簡單的后端功能
文章將webpack的配置文件寫成了三份:公用部分文件、開發環境文件、線上環境文件,具體在文章中會有詳細的介紹。
注意:文章介紹很詳細,適合新手入門使用,請耐心閱讀。
二 正文 1.path相關內容文檔:http://nodejs.cn/api/path.html
我們經常用到的就是path.resolve和path.join,那么我們就講一下兩者的用法和區別:
相關文章:Difference between path.resolve and path.join invocation?
(1)path.join
path.join() 方法使用平臺特定的分隔符把全部給定的 path 片段連接到一起,并規范化生成的路徑。
path.join("/a", "/b") // Outputs "/a/b" path.join("/foo", "bar", "baz/asdf", "quux", ".."); // outputs "/foo/bar/baz/asdf"
summary:path.join通常用到的是簡單的將字符串進行拼接。
(2)path.resolve
path.resolve() 方法會把一個路徑或路徑片段的序列解析為一個絕對路徑。
給定的路徑的序列是從右往左被處理的,后面每個 path 被依次解析,直到構造完成一個絕對路徑(就會停止解析)。
例如,給定的路徑片段的序列為:/foo、/bar、baz,則調用 path.resolve("/foo", "/bar", "baz") 會返回 /bar/baz。
如果處理完全部給定的 path 片段后還未生成一個絕對路徑,則當前工作目錄會被用上。
生成的路徑是規范化后的,且末尾的斜杠會被刪除,除非路徑被解析為根目錄。
長度為零的 path 片段會被忽略。
如果沒有傳入 path 片段,則 path.resolve() 會返回當前工作目錄的絕對路徑。
例子:
path.resolve("/foo/bar", "./baz"); // 返回: "/foo/bar/baz" path.resolve("/foo/bar", "/tmp/file/"); // 返回: "/tmp/file
(3)work directory 與 dirname
工作目錄和文件目錄并不是一直相等,我們以"./src/view/index.js"文件為例:
文件目錄是固定的,就是文件所在的目錄:./src/view/index.js
工作目錄是不確定的,查看當前所在目錄:pwd
如果你是在./src/view/ 下執行的index.js,那么就和文件路徑相同./src/view/index.js 但是如果你在./src下執行的index.js,那工作路徑則是./src2.從server.js談起
我們要知道server.js都做了些什么:
1.開啟一個http服務器
2.使用熱編譯中間件,實時編譯修改過的內容
3.使用熱替換,實時查看最新的頁面UI
4.【擴展】可以做一些后端的東西
代碼如下:
const http = require("http"); const webpack = require("webpack"); const webpackDevMiddleware = require("webpack-dev-middleware"); const webpackHotMiddleware = require("webpack-hot-middleware"); // 使用express啟用一個服務器 const express = require("express"); // 引用開發環境下的webpack配置文件 const config = require("./webpack.dev"); const app = express(); const webpackConfig = webpack(config); const devMiddlewareCompiler = webpackDevMiddleware(webpackConfig,{ publicPath:config.output.publicPath }); const hotMiddlewareCompiler = webpackHotMiddleware(webpackConfig,{ log: false, heartbeat: 2000, }) app.use(devMiddlewareCompiler);// 使用熱編譯中間件 app.use(hotMiddlewareCompiler);// 使用熱替換中間件 app.listen(8080,function(){ console.log("Example app listening on port 8080! "); });
注意:為什么要把熱編譯的功能放在node里面呢?如果引用wepack-dev-server會自動管理熱編譯,它的原理也還是利用express開啟了一個小型服務器,只不過我們看不到它。所以如果你要自己控制,并且想簡單方便的在后端做點小東西,可以完全使用上面的方法。如果是后端比較重就不建議這么寫了,你需要開啟兩臺服務,通過代理的方式模擬進行前后端通信了。
3.webpack commonwebpack.common,js配置了無論是開發還是發布都需要的東西,比如一些loader的轉譯,代碼的打包壓縮等。
具體代碼如下:
const path = require("path"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { entry: { app: "./src/index.js" // 入口文件index.js }, module:{ rules:[{ test:/.css$/, use:[ "style-loader", "css-loader" ], }, { test: /.(png|svg|jpg|gif)$/, use: [ "file-loader" ] }, { test: /.(woff|woff2|eot|ttf|otf)$/, use: [ "file-loader" ] } ], }, plugins: [ new CleanWebpackPlugin(["dist"]), new HtmlWebpackPlugin({ title: "Production" }), ], output: { filename: "[name].bundle.js", path: path.resolve(__dirname, "dist"), } };
下面講一講主要做了什么事:
3-1 file-loader
a. 加載圖片
如果我們要想像引用模塊那樣引用一個圖片,例如:
import Rose from "./img/rose.jpg"
在 webpack 里負責圖片翻譯的是 file-loader。而且,webpack 在最終構建時,會自動將模塊中引用的圖片拷貝到相應目錄。如果你檢查此元素,你將看到實際的文件名已更改為像 5c999da72346a995e7e2718865d019c8.png 一樣。這意味著 webpack 在 src 文件夾中找到我們的文件,并成功處理過它!
b. 加載字體
css文件中引用字體:
@font-face { font-family: "MyFont"; src: url("./my-font.woff2") format("woff2"), url("./my-font.woff") format("woff"); font-weight: 600; font-style: normal; }
【擴展】file-loader與url-loader
如果我們希望在頁面引入圖片(包括img的src和background的url)。當我們基于webpack進行開發時,引入圖片會遇到一些問題。其中一個就是引用路徑的問題。拿background樣式用url引入背景圖來說,我們都知道,webpack最終會將各個模塊打包成一個文件,因此我們樣式中的url路徑是相對入口html頁面的,而不是相對于原始css文件所在的路徑的。這就會導致圖片引入失敗。這個問題是用file-loader解決的,file-loader可以解析項目中的url引入(不僅限于css),根據我們的配置,將圖片拷貝到相應的路徑,再根據我們的配置,修改打包后文件引用路徑,使之指向正確的文件。另外,如果圖片較多,會發很多http請求,會降低頁面性能。這個問題可以通過url-loader解決。url-loader會將引入的圖片編碼,生成dataURl。相當于把圖片數據翻譯成一串字符。再把這串字符打包到文件中,最終只需要引入這個文件就能訪問圖片了。當然,如果圖片較大,編碼會消耗性能。因此url-loader提供了一個limit參數,小于limit字節的文件會被轉為DataURl,大于limit的還會使用file-loader進行copy。
//url-loader封裝了file-loader。url-loader不依賴于file-loader,即使用url-loader時,只需要安裝url-loader即可 // webpack.config.js module.exports = { module: { rules: [ { test: /.(png|jpg|gif)$/, use: [ { loader: "url-loader", options: { limit: 8192 } } ] } ] } }
3-2 css loader與style-loader
如果你在JS中使用:
import "./index.css"
我們需要 CSS 加載器:
(1) css-loader - 預處理 CSS 文件
(2) style-loader - 將 CSS 插入到 DOM 中的 style 標簽
要查看 webpack 做了什么,請檢查頁面(不要查看頁面源代碼,因為它不會顯示結果),并查看頁面的 head 標簽。它應該包含我們在 index.js 中導入的 style 塊元素:。
注意:
(1)加載器的順序是從后往前的,loader 的順序很重要:如果把 style-loader 放到 css-loader 后面,我們就會撞見錯誤。
(2)我們如果只使用了 css-loader,則 webpack 只是將 CSS 文件預處理成模塊然后打包到構建文件中,并不會插入到頁面。
【擴展】將CSS多帶帶打包:
webpack1/2/3:extract-text-webpack-plugin
webpack4:mini-css-extract-plugin
3-3 htm-lwebpack-plugin
詳細介紹見:html-webpack-plugin npm
這是一個webpack插件,可以簡化創建HTML文件以便為webpack包提供服務。 這對于webpack包來說特別有用,它在文件名中包含一個hash,用于更改每個編譯。 你可以讓插件為你生成一個HTML文件,使用lodash模板提供你自己的模板或使用你自己的加載器。
3-4 clean-webpack-plugin
詳細介紹見:clean-wenpack-plugin
一個在創建之前清除你build文件夾的webpack插件。在打包生成新的build文件的時候清除之前生成的,這非常有用。
兩種環境的配置在webpack4中都支持mode的配置:development/production,具體的默認配置查詢可以移步這里:webpack4 Mode的默認設置 。
webpack.dev.config.js:
const webpack = require("webpack"); const merge = require("webpack-merge"); const common = require("./webpack.common.js"); module.exports = merge(common, { mode:"development", plugins:[ new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin(), ] });
這里做了兩件事:
(1)mode:"development":定義環境為開發環境。在webpack4之后省了很多操作,只需要指定為開發環境,就會自動設定source map等信息
(2)HotModuleReplacementPlugin:模塊熱替換
使用熱替換需要兩步:
首先: Add the following plugins to the plugins array
plugins: [ // OccurenceOrderPlugin is needed for webpack 1.x only new webpack.optimize.OccurenceOrderPlugin(), new webpack.HotModuleReplacementPlugin(), // Use NoErrorsPlugin for webpack 1.x new webpack.NoEmitOnErrorsPlugin() ] Occurence ensures consistent build hashes, hot module replacement is somewhat self-explanatory, no errors is used to handle errors more cleanly.
其次:Add "webpack-hot-middleware/client" into the entry array.
This connects to the server to receive notifications when the bundle rebuilds and then updates your client bundle accordingly.5.webpack production
兩種環境的配置在webpack4中都支持mode的配置:development/production,具體的默認配置查詢可以移步這里:webpack4 Mode的默認設置 。
const webpack = require("webpack"); const path = require("path"); const merge = require("webpack-merge"); // const UglifyJSPlugin = require("uglifyjs-webpack-plugin"); const common = require("./webpack.common.js"); module.exports = merge(common, { output:{ // publicPath:path.resolve(__dirname, "dist"), }, mode:"production", });
指定環境為生產環境,默認開啟UglifyJSPlugin。
【擴展】將文件標記為無副作用(side-effect-free)
src/math.js:
export function square(x) { return x * x; } export function cube(x) { return x * x * x; }
src/index.js:
import { cube } from "./math.js";
math.js文件的square函數沒有被導入,但是,它仍然被包含在 bundle 中。
在一個純粹的 ESM 模塊世界中,識別出哪些文件有副作用很簡單。然而,我們的項目無法達到這種純度,所以,此時有必要向 webpack 的 compiler 提供提示哪些代碼是“純粹部分”。
這種方式是通過 package.json 的 "sideEffects" 屬性來實現的。
{ "name": "your-project", "sideEffects": false }
如同上面提到的,如果所有代碼都不包含副作用,我們就可以簡單地將該屬性標記為 false,來告知 webpack,它可以安全地刪除未用到的 export 導出。
如果你的代碼確實有一些副作用,那么可以改為提供一個數組:
{ "name": "your-project", "sideEffects": [ "./src/some-side-effectful-file.js" ] }三 后記
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/95528.html
摘要:它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。安裝和使用在之后的實踐過程中講解。有一套良好的代碼規范,對于項目的開發和維護都很友好。 努力了,不一定能成功,但是不努力,感覺好舒服啊 ——努訓 沒有了解過vue1.*,直接上手vue2.0;雖然有些吃力但還是很愉快了學下來了。 一丶環境配置 node.js...
摘要:它可以讓你在沒有任何構建工具例如或等工具配置經驗的情況下,幫你快速生成一個完整的前端工程,并可以打包代碼和靜態資源,使你的項目以最優異的性能上線。針對痛點零配置,快速搭建繁瑣的開發環境搭建。自適應解決方案實現多終端顯示一致。 X-BUILD一套基于Webpack(v4.21.0)快速搭建H5場景開發環境的腳手架,只需要幾分鐘的時間就可以運行起來。X-BUILD是針對H5開發的一套自動化...
摘要:什么是單頁面應用單頁面應用是指用戶在瀏覽器加載單一的頁面,后續請求都無需再離開此頁目標旨在用為用戶提供了更接近本地移動或桌面應用程序的體驗。流程第一次請求時,將導航頁傳輸到客戶端,其余請求通過獲取數據實現數據的傳輸通過或遠程過程調用。 什么是單頁面應用(SPA)? 單頁面應用(SPA)是指用戶在瀏覽器加載單一的HTML頁面,后續請求都無需再離開此頁 目標:旨在用為用戶提供了更接近本地...
閱讀 1886·2021-09-22 15:29
閱讀 3362·2019-08-30 15:44
閱讀 3571·2019-08-30 15:43
閱讀 1771·2019-08-30 13:48
閱讀 1498·2019-08-29 13:56
閱讀 2483·2019-08-29 12:12
閱讀 977·2019-08-26 11:35
閱讀 1060·2019-08-26 10:25