摘要:一前言文章介紹了一個(gè)現(xiàn)代化的項(xiàng)目的環(huán)境是什么樣的。其中一個(gè)就是引用路徑的問(wèn)題。擴(kuò)展將多帶帶打包詳細(xì)介紹見(jiàn)這是一個(gè)插件,可以簡(jiǎn)化創(chuàng)建文件以便為包提供服務(wù)。兩種環(huán)境的配置在中都支持的配置具體的默認(rèn)配置查詢可以移步這里的默認(rèn)設(shè)置。
一 前言
文章介紹了一個(gè)現(xiàn)代化的項(xiàng)目的webpack4環(huán)境是什么樣的。這里只是介紹了基礎(chǔ)的功能,如果需要詳細(xì)的相關(guān)只是可以去webpack官網(wǎng)去查閱。
代碼地址:github
環(huán)境特點(diǎn):
1.使用了webpack-dev-middleware,在文件內(nèi)容更改之后自動(dòng)編譯;
2.使用了webpack-hot-middleware,在熱編譯之后會(huì)自動(dòng)刷新頁(yè)面更改的內(nèi)容,而不是刷新整個(gè)頁(yè)面
3.使用了server.js文件來(lái)自己控制啟動(dòng)http服務(wù),后期可以擴(kuò)展簡(jiǎn)單的后端功能
文章將webpack的配置文件寫(xiě)成了三份:公用部分文件、開(kāi)發(fā)環(huán)境文件、線上環(huán)境文件,具體在文章中會(huì)有詳細(xì)的介紹。
注意:文章介紹很詳細(xì),適合新手入門使用,請(qǐng)耐心閱讀。
二 正文 1.path相關(guān)內(nèi)容文檔:http://nodejs.cn/api/path.html
我們經(jīng)常用到的就是path.resolve和path.join,那么我們就講一下兩者的用法和區(qū)別:
相關(guān)文章:Difference between path.resolve and path.join invocation?
(1)path.join
path.join() 方法使用平臺(tái)特定的分隔符把全部給定的 path 片段連接到一起,并規(guī)范化生成的路徑。
path.join("/a", "/b") // Outputs "/a/b" path.join("/foo", "bar", "baz/asdf", "quux", ".."); // outputs "/foo/bar/baz/asdf"
summary:path.join通常用到的是簡(jiǎn)單的將字符串進(jìn)行拼接。
(2)path.resolve
path.resolve() 方法會(huì)把一個(gè)路徑或路徑片段的序列解析為一個(gè)絕對(duì)路徑。
給定的路徑的序列是從右往左被處理的,后面每個(gè) path 被依次解析,直到構(gòu)造完成一個(gè)絕對(duì)路徑(就會(huì)停止解析)。
例如,給定的路徑片段的序列為:/foo、/bar、baz,則調(diào)用 path.resolve("/foo", "/bar", "baz") 會(huì)返回 /bar/baz。
如果處理完全部給定的 path 片段后還未生成一個(gè)絕對(duì)路徑,則當(dāng)前工作目錄會(huì)被用上。
生成的路徑是規(guī)范化后的,且末尾的斜杠會(huì)被刪除,除非路徑被解析為根目錄。
長(zhǎng)度為零的 path 片段會(huì)被忽略。
如果沒(méi)有傳入 path 片段,則 path.resolve() 會(huì)返回當(dāng)前工作目錄的絕對(duì)路徑。
例子:
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
工作目錄是不確定的,查看當(dāng)前所在目錄:pwd
如果你是在./src/view/ 下執(zhí)行的index.js,那么就和文件路徑相同./src/view/index.js 但是如果你在./src下執(zhí)行的index.js,那工作路徑則是./src2.從server.js談起
我們要知道server.js都做了些什么:
1.開(kāi)啟一個(gè)http服務(wù)器
2.使用熱編譯中間件,實(shí)時(shí)編譯修改過(guò)的內(nèi)容
3.使用熱替換,實(shí)時(shí)查看最新的頁(yè)面UI
4.【擴(kuò)展】可以做一些后端的東西
代碼如下:
const http = require("http"); const webpack = require("webpack"); const webpackDevMiddleware = require("webpack-dev-middleware"); const webpackHotMiddleware = require("webpack-hot-middleware"); // 使用express啟用一個(gè)服務(wù)器 const express = require("express"); // 引用開(kāi)發(fā)環(huán)境下的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會(huì)自動(dòng)管理熱編譯,它的原理也還是利用express開(kāi)啟了一個(gè)小型服務(wù)器,只不過(guò)我們看不到它。所以如果你要自己控制,并且想簡(jiǎn)單方便的在后端做點(diǎn)小東西,可以完全使用上面的方法。如果是后端比較重就不建議這么寫(xiě)了,你需要開(kāi)啟兩臺(tái)服務(wù),通過(guò)代理的方式模擬進(jìn)行前后端通信了。
3.webpack commonwebpack.common,js配置了無(wú)論是開(kāi)發(fā)還是發(fā)布都需要的東西,比如一些loader的轉(zhuǎn)譯,代碼的打包壓縮等。
具體代碼如下:
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. 加載圖片
如果我們要想像引用模塊那樣引用一個(gè)圖片,例如:
import Rose from "./img/rose.jpg"
在 webpack 里負(fù)責(zé)圖片翻譯的是 file-loader。而且,webpack 在最終構(gòu)建時(shí),會(huì)自動(dòng)將模塊中引用的圖片拷貝到相應(yīng)目錄。如果你檢查此元素,你將看到實(shí)際的文件名已更改為像 5c999da72346a995e7e2718865d019c8.png 一樣。這意味著 webpack 在 src 文件夾中找到我們的文件,并成功處理過(guò)它!
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; }
【擴(kuò)展】file-loader與url-loader
如果我們希望在頁(yè)面引入圖片(包括img的src和background的url)。當(dāng)我們基于webpack進(jìn)行開(kāi)發(fā)時(shí),引入圖片會(huì)遇到一些問(wèn)題。其中一個(gè)就是引用路徑的問(wèn)題。拿background樣式用url引入背景圖來(lái)說(shuō),我們都知道,webpack最終會(huì)將各個(gè)模塊打包成一個(gè)文件,因此我們樣式中的url路徑是相對(duì)入口html頁(yè)面的,而不是相對(duì)于原始css文件所在的路徑的。這就會(huì)導(dǎo)致圖片引入失敗。這個(gè)問(wèn)題是用file-loader解決的,file-loader可以解析項(xiàng)目中的url引入(不僅限于css),根據(jù)我們的配置,將圖片拷貝到相應(yīng)的路徑,再根據(jù)我們的配置,修改打包后文件引用路徑,使之指向正確的文件。另外,如果圖片較多,會(huì)發(fā)很多http請(qǐng)求,會(huì)降低頁(yè)面性能。這個(gè)問(wèn)題可以通過(guò)url-loader解決。url-loader會(huì)將引入的圖片編碼,生成dataURl。相當(dāng)于把圖片數(shù)據(jù)翻譯成一串字符。再把這串字符打包到文件中,最終只需要引入這個(gè)文件就能訪問(wèn)圖片了。當(dāng)然,如果圖片較大,編碼會(huì)消耗性能。因此url-loader提供了一個(gè)limit參數(shù),小于limit字節(jié)的文件會(huì)被轉(zhuǎn)為DataURl,大于limit的還會(huì)使用file-loader進(jìn)行copy。
//url-loader封裝了file-loader。url-loader不依賴于file-loader,即使用url-loader時(shí),只需要安裝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 - 預(yù)處理 CSS 文件
(2) style-loader - 將 CSS 插入到 DOM 中的 style 標(biāo)簽
要查看 webpack 做了什么,請(qǐng)檢查頁(yè)面(不要查看頁(yè)面源代碼,因?yàn)樗粫?huì)顯示結(jié)果),并查看頁(yè)面的 head 標(biāo)簽。它應(yīng)該包含我們?cè)?index.js 中導(dǎo)入的 style 塊元素:。
注意:
(1)加載器的順序是從后往前的,loader 的順序很重要:如果把 style-loader 放到 css-loader 后面,我們就會(huì)撞見(jiàn)錯(cuò)誤。
(2)我們?nèi)绻皇褂昧?css-loader,則 webpack 只是將 CSS 文件預(yù)處理成模塊然后打包到構(gòu)建文件中,并不會(huì)插入到頁(yè)面。
【擴(kuò)展】將CSS多帶帶打包:
webpack1/2/3:extract-text-webpack-plugin
webpack4:mini-css-extract-plugin
3-3 htm-lwebpack-plugin
詳細(xì)介紹見(jiàn):html-webpack-plugin npm
這是一個(gè)webpack插件,可以簡(jiǎn)化創(chuàng)建HTML文件以便為webpack包提供服務(wù)。 這對(duì)于webpack包來(lái)說(shuō)特別有用,它在文件名中包含一個(gè)hash,用于更改每個(gè)編譯。 你可以讓插件為你生成一個(gè)HTML文件,使用lodash模板提供你自己的模板或使用你自己的加載器。
3-4 clean-webpack-plugin
詳細(xì)介紹見(jiàn):clean-wenpack-plugin
一個(gè)在創(chuàng)建之前清除你build文件夾的webpack插件。在打包生成新的build文件的時(shí)候清除之前生成的,這非常有用。
兩種環(huán)境的配置在webpack4中都支持mode的配置:development/production,具體的默認(rèn)配置查詢可以移步這里:webpack4 Mode的默認(rèn)設(shè)置 。
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":定義環(huán)境為開(kāi)發(fā)環(huán)境。在webpack4之后省了很多操作,只需要指定為開(kāi)發(fā)環(huán)境,就會(huì)自動(dòng)設(shè)定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
兩種環(huán)境的配置在webpack4中都支持mode的配置:development/production,具體的默認(rèn)配置查詢可以移步這里:webpack4 Mode的默認(rèn)設(shè)置 。
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", });
指定環(huán)境為生產(chǎn)環(huán)境,默認(rèn)開(kāi)啟UglifyJSPlugin。
【擴(kuò)展】將文件標(biāo)記為無(wú)副作用(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函數(shù)沒(méi)有被導(dǎo)入,但是,它仍然被包含在 bundle 中。
在一個(gè)純粹的 ESM 模塊世界中,識(shí)別出哪些文件有副作用很簡(jiǎn)單。然而,我們的項(xiàng)目無(wú)法達(dá)到這種純度,所以,此時(shí)有必要向 webpack 的 compiler 提供提示哪些代碼是“純粹部分”。
這種方式是通過(guò) package.json 的 "sideEffects" 屬性來(lái)實(shí)現(xiàn)的。
{ "name": "your-project", "sideEffects": false }
如同上面提到的,如果所有代碼都不包含副作用,我們就可以簡(jiǎn)單地將該屬性標(biāo)記為 false,來(lái)告知 webpack,它可以安全地刪除未用到的 export 導(dǎo)出。
如果你的代碼確實(shí)有一些副作用,那么可以改為提供一個(gè)數(shù)組:
{ "name": "your-project", "sideEffects": [ "./src/some-side-effectful-file.js" ] }三 后記
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95528.html
摘要:它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。安裝和使用在之后的實(shí)踐過(guò)程中講解。有一套良好的代碼規(guī)范,對(duì)于項(xiàng)目的開(kāi)發(fā)和維護(hù)都很友好。 努力了,不一定能成功,但是不努力,感覺(jué)好舒服啊 ——努訓(xùn) 沒(méi)有了解過(guò)vue1.*,直接上手vue2.0;雖然有些吃力但還是很愉快了學(xué)下來(lái)了。 一丶環(huán)境配置 node.js...
摘要:它可以讓你在沒(méi)有任何構(gòu)建工具例如或等工具配置經(jīng)驗(yàn)的情況下,幫你快速生成一個(gè)完整的前端工程,并可以打包代碼和靜態(tài)資源,使你的項(xiàng)目以最優(yōu)異的性能上線。針對(duì)痛點(diǎn)零配置,快速搭建繁瑣的開(kāi)發(fā)環(huán)境搭建。自適應(yīng)解決方案實(shí)現(xiàn)多終端顯示一致。 X-BUILD一套基于Webpack(v4.21.0)快速搭建H5場(chǎng)景開(kāi)發(fā)環(huán)境的腳手架,只需要幾分鐘的時(shí)間就可以運(yùn)行起來(lái)。X-BUILD是針對(duì)H5開(kāi)發(fā)的一套自動(dòng)化...
摘要:什么是單頁(yè)面應(yīng)用單頁(yè)面應(yīng)用是指用戶在瀏覽器加載單一的頁(yè)面,后續(xù)請(qǐng)求都無(wú)需再離開(kāi)此頁(yè)目標(biāo)旨在用為用戶提供了更接近本地移動(dòng)或桌面應(yīng)用程序的體驗(yàn)。流程第一次請(qǐng)求時(shí),將導(dǎo)航頁(yè)傳輸?shù)娇蛻舳?,其余?qǐng)求通過(guò)獲取數(shù)據(jù)實(shí)現(xiàn)數(shù)據(jù)的傳輸通過(guò)或遠(yuǎn)程過(guò)程調(diào)用。 什么是單頁(yè)面應(yīng)用(SPA)? 單頁(yè)面應(yīng)用(SPA)是指用戶在瀏覽器加載單一的HTML頁(yè)面,后續(xù)請(qǐng)求都無(wú)需再離開(kāi)此頁(yè) 目標(biāo):旨在用為用戶提供了更接近本地...
閱讀 1884·2021-09-22 15:29
閱讀 3361·2019-08-30 15:44
閱讀 3570·2019-08-30 15:43
閱讀 1769·2019-08-30 13:48
閱讀 1497·2019-08-29 13:56
閱讀 2483·2019-08-29 12:12
閱讀 977·2019-08-26 11:35
閱讀 1059·2019-08-26 10:25