中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

html5做網(wǎng)站鏈接范例網(wǎng)站推廣100種方法

html5做網(wǎng)站鏈接范例,網(wǎng)站推廣100種方法,wordpress日文版,推廣策劃書模板module federation是什么 webpack5新增了module federation,module federation的作用,將每個構(gòu)建(build)作為容器(這是一個概念),構(gòu)建后的資源可以正常部署,同時還具備在運行時對外暴露其中的模塊,這就意味著多個構(gòu)建…

module federation是什么

webpack5新增了module federation,module federation的作用,將每個構(gòu)建(build)作為容器(這是一個概念),構(gòu)建后的資源可以正常部署,同時還具備在運行時對外暴露其中的模塊,這就意味著多個構(gòu)建可以獨立完成,獨立部署,所需的依賴可以在運行時加載。對于多個構(gòu)建公共的依賴,可以通過shared來指定,這些依賴也可以在運行時加載,并且只加載一次。

事實上,公共依賴模塊也可以通過npm包的形式來實現(xiàn)共享,這種方式的共享不得不依賴于app shell這種容器預先加載共享包。module federation只在第一次加載模塊A時加載共享包,加載模塊B時共享包已被緩存。

模塊與容器的概念有點重疊,容器實際上是一些模塊的集合,與構(gòu)建相關(guān),是我們傳統(tǒng)意義上的bundle,只是在加入module federation能力后,容器可以對外導出成員,這一點跟模塊比較接近而已。

這種能力剛好與微前端架構(gòu)所需的前端集成能力一致。前端集成技術(shù),就是應用A將應用B、C等應用的某些頁面、組件、片段等等,集成到自己頁面里。

加入module federation的構(gòu)建

傳統(tǒng)的構(gòu)建過程,模塊之間如果存在依賴關(guān)系,這些模塊會在一個構(gòu)建過程中打包成一個bundle。

而module federation讓這種存在依賴關(guān)系的模塊,各自有各自的構(gòu)建過程,并各自實現(xiàn)自己的bundle和部署,最終在運行時異步獲取依賴模塊。這種方式提高了模塊的自主性,但可能因為異步的原因,降低了首屏渲染性能、運行時的用戶交互體驗等等。

有對外導出的容器示例

這里展示一個module federation的示例使用。products項目展示一些產(chǎn)品名稱,其工程目錄如下

- products/- public/- index.html // 模板- src/- bootstrap.js // 導入faker生成假數(shù)據(jù),導出一個mount方法,將html內(nèi)容掛載到某個DOM節(jié)點上- index.js  // 入口文件,導入bootstrap.js模塊- package.json - webpack.config.js // 配置module federation的配置文件

bootstrap.js的內(nèi)容如下

// 聲明為shared的模塊,會被拆分為異步模塊,所以需要異步加載
const faker = await import("faker");function mount(el) {let products = "";for (let i = 1; i <= 5; i++) {products += `<div>${faker.commerce.productName()}</div>`;}el.innerHTML = products;
}if (process.env.NODE_ENV === "development") {// 依賴該模塊的容器,必須提供一個id屬性為'dev-products'的DOM元素const el = document.querySelector("#dev-products");if (el) mount(el);
}export { mount };
構(gòu)建產(chǎn)物

webpack的module federation相關(guān)配置示例

  devServer: {port: 8081,},// 省略其他傳統(tǒng)的配置plugins: [new ModuleFederationPlugin({name: "products", // 當前容器的名稱,其他容器導入該容器時的標識filename: "remoteEntry.js", // 當前容器的入口文件,與output.filename不是一回事exposes: {// 導出成員對應的模塊會被拆離為異步模塊"./Index": "./src/bootstrap.js", // 指定對外暴露的模塊列表,標識符: 模塊地址},shared: { // 公共的共享模塊,其他容器也會使用faker這個模塊,共享模塊在構(gòu)建產(chǎn)物會被作為單獨的包存在,由容器異步加載faker: {singleton: true,},},}),
],

在加入module federation的webpack配置下,構(gòu)建產(chǎn)物發(fā)生了一定的變化,除了傳統(tǒng)的bundle外,還會有如下產(chǎn)物

  • module federation插件產(chǎn)生的容器入口文件,如上面配置的remoteEntry.js;
  • 對外暴露的模塊,如上面配置的"./Index": "./src/bootstrap.js"的產(chǎn)物src_bootstrap_js.js;
  • 共享模塊,如上面配置的faker,產(chǎn)物是vendors-node_modules_faker_index_js.js;

而通過模板生成的index.html中,不僅有傳統(tǒng)的bundle產(chǎn)物main.js,也會有remoteEntry.js。對于傳統(tǒng)的部署而言,remoteEntry.js是沒必要的。main.js與remoteEntry.js有很多重復的webpack膠水代碼。

容器對外的入口文件remoteEntry.js

查看由module federation生成的容器入口文件,可以看到與傳統(tǒng)的bundle不一樣的地方在于,容器入口文件包含一個變量聲明var products, 與配置name: "products"一致。

remoteEntry.js會包含一個moduleMap,包含模塊標識符’./Index’與src_bootstrap_js.js

remoteEntry.js包含本地容器的初始化init方法和獲取導出成員get方法,被加載后導出了products變量,攜帶init和get方法。

/***/ // "webpack/container/entry/products":
/*!***********************!*\!*** container entry ***!\***********************/
/*** remoteEntry.js中 "webpack/container/entry/products" 對應的函數(shù)內(nèi)部的eval代碼整理如下*/var moduleMap = {"./Index": () => {return __webpack_require__.e("src_bootstrap_js").then(() => () =>__webpack_require__(/*! ./src/bootstrap.js */ "./src/bootstrap.js"));},
};
// container的getter,將container中的module加載,并返回加載后的module
var get = (module, getScope) => {__webpack_require__.R = getScope;getScope = __webpack_require__.o(moduleMap, module)? moduleMap[module](): Promise.resolve().then(() => {throw new Error('Module "' + module + '" does not exist in container.');});__webpack_require__.R = undefined;return getScope;
};
// 初始化容器,通過shareScope來提供對外共享的module,如果聲明了shared,每個build都會有shared的module,即便有重復
// 如果共享module已經(jīng)被使用了,那么該容器的共享module會被忽略,但會作為fallback
var init = (shareScope, initScope) => {if (!__webpack_require__.S) return;var name = "default";var oldScope = __webpack_require__.S[name];if (oldScope && oldScope !== shareScope)throw new Error("Container initialization failed as it has already been initialized with a different share scope");__webpack_require__.S[name] = shareScope;return __webpack_require__.I(name, initScope);
};// This exports getters to disallow modifications
__webpack_require__.d(exports, {get: () => get,init: () => init,
});//# sourceURL=webpack://products/container_entry?;

有導入其他容器的容器示例

通常導入別的容器的容器會作為一個app shell,加載其他容器的模塊,這正是微前端的客戶端集成方案。這里的container項目,加載products的bootstrap模塊,使用mount方法掛載HTML內(nèi)容。目錄示例如下

- container/- public/- index.html // 模板- src/- bootstrap.js // 導入products的bootstrap模塊,使用mount方法,將html內(nèi)容掛載到某個DOM節(jié)點上- index.js  // 入口文件,導入bootstrap.js模塊- package.json - webpack.config.js // 配置module federation的配置文件

其中,bootstrap.js的內(nèi)容如下

// 這里不使用const { mount: mountProducts } = await import("products/Index")的語法
// 是因為模塊本身不導入導出任何成員,webpack不認為是ESM,只有ESM才能使用頂層的await語法
// 在這種情況下,使用import ESM語法,那么index.js必須使用import('./bootstrap.js')的動態(tài)導入語法,因為遠程模塊的導入必須是異步的
import { mount as mountProducts } from "products/Index"
// 模板index.html中已經(jīng)有<div id="prod-products"></div>
mountProducts(document.querySelector("#prod-products"));

相關(guān)的module federation配置如下

  devServer: {port: 8080},plugins: [new ModuleFederationPlugin({name: "container", // 容器名稱remotes: { // 指定遠程模塊依賴// 模塊別名: '模塊別名@模塊入口地址',模塊別名是要在代碼里導入該模塊成員時使用products: "products@http://localhost:8081/remoteEntry.js", // 模塊名稱: 模塊地址}}),

container容器應用可以拿到products容器應用的bootstrap模塊,使用mount方法來掛載HTML內(nèi)容了??梢試L試一下,啟動8080端口,可以看到頁面有一些由products容器應用的bootstrap模塊掛載的HTML內(nèi)容。

構(gòu)建產(chǎn)物

由于container容器沒有對外暴露的模塊,因此沒有remoteEntry.js這樣的入口文件,也沒有共享模塊,所以container容器的構(gòu)建產(chǎn)物與傳統(tǒng)的構(gòu)建一致,只有bundle。bundle文件中,有包含products容器的引用和模塊加載代碼

/***/ "webpack/container/reference/products":
/*!****************************************************************!*\!*** external "products@http://localhost:8081/remoteEntry.js" ***!\****************************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {var __webpack_error__ = new Error();
module.exports = new Promise((resolve, reject) => {if(typeof products !== "undefined") return resolve();__webpack_require__.l("http://localhost:8081/remoteEntry.js", (event) => {if(typeof products !== "undefined") return resolve();var errorType = event && (event.type === 'load' ? 'missing' : event.type);var realSrc = event && event.target && event.target.src;__webpack_error__.message = 'Loading script failed.\n(' + errorType + ': ' + realSrc + ')';__webpack_error__.name = 'ScriptExternalLoadError';__webpack_error__.type = errorType;__webpack_error__.request = realSrc;reject(__webpack_error__);}, "products");
}).then(() => (products));/***/ })

模塊成員標識符規(guī)則

模塊對外導出的成員應該如何標識?例如,products對外導出的./Index能不能寫成’Index’或者’Hello’?

在導入成員時,使用import xxx from 'products/Index',webpack會轉(zhuǎn)換為’./Index’作為模塊標識符,因此products對外導出成員時的標識符不能隨意寫,要按照規(guī)則./[name]的形式來書寫;
webpack內(nèi)部使用了一系列映射關(guān)系來確定導出成員,如下面代碼所示

        var chunkMapping = {/******/ // src/bootstrap.js中導入了products/Index和products/World"src_bootstrap_js": [/******/ "webpack/container/remote/products/Index", /******/"webpack/container/remote/products/World"/******/]/******/};/******/var idToExternalAndNameMapping = {/******/"webpack/container/remote/products/Index": [/******/"default", /******/"./Index", /******/ 導入成員的標識符"webpack/container/reference/products"/******/],/******/"webpack/container/remote/products/World": [/******/"default", /******/"./World", /******/ 導入成員的標識符"webpack/container/reference/products"/******/]/******/};

異步模塊有異步依賴時使用異步導入還是同步導入

module federation導致的模塊拆分,如果是異步模塊A依賴了異步模塊B,在A中可以同步導入模塊Bimport xxx from 'module-B',因為webpack會使用Promise.all來加載模塊A和被A依賴的模塊B。所以只要使用動態(tài)導入`import(‘module-A’)即可,不需要在A中使用動態(tài)導入B了。當然,動態(tài)導入B模塊也是可以的。

總結(jié)

module federation是一種支持當前應用在運行時加載其他運行時應用內(nèi)部模塊的技術(shù),在webpack配置時,當前應用需要用remote指定要加載的應用名稱, 其他應用使用exposes指定對外暴露的內(nèi)部模塊,使用shared指定公共的共享模塊。應用可以各自獨立構(gòu)建,獨立部署,只在運行時產(chǎn)生耦合(加載)。各個應用在開發(fā)構(gòu)建時都是獨立的,降低了開發(fā)構(gòu)建時的耦合性。

http://www.risenshineclean.com/news/35524.html

相關(guān)文章:

  • 中國建設(shè)銀行安徽分行網(wǎng)站推廣什么軟件可以長期賺錢
  • 珍島信息技術(shù)有限公司做網(wǎng)站服務(wù)網(wǎng)上營銷方式和方法
  • 直播網(wǎng)站開發(fā)核心技術(shù)如何做營銷策劃方案
  • 小企業(yè)網(wǎng)站建設(shè)怎樣網(wǎng)絡(luò)優(yōu)化工程師騙局
  • 上傳網(wǎng)站的三種方法網(wǎng)絡(luò)營銷工程師
  • 做網(wǎng)站申請什么商標seo咨詢服務(wù)價格
  • 小說網(wǎng)站虛擬主機網(wǎng)絡(luò)促銷
  • 建一個類似b站的網(wǎng)站多少錢百度用戶服務(wù)中心官網(wǎng)電話
  • 做搞笑視頻網(wǎng)站靠神魔賺錢好的競價推廣外包公司
  • 2018網(wǎng)站外鏈怎么做谷歌seo顧問
  • 棗莊網(wǎng)站設(shè)計淘寶指數(shù)在線查詢
  • 手機做網(wǎng)站怎么做網(wǎng)站快速收錄工具
  • 做游戲小網(wǎng)站是啥重慶百度seo整站優(yōu)化
  • 企業(yè)公司網(wǎng)站管理系統(tǒng)免費建站免費推廣的網(wǎng)站
  • 在網(wǎng)站插入微博靜態(tài)的網(wǎng)頁出的來到服務(wù)器出不來網(wǎng)站建設(shè)流程圖
  • 創(chuàng)意經(jīng)濟型網(wǎng)站建設(shè)個人網(wǎng)站推廣怎么做
  • 直銷軟件網(wǎng)站開發(fā)網(wǎng)站權(quán)重怎么提高
  • 新聞網(wǎng)站建設(shè)項目可行性報告網(wǎng)站媒體推廣方案
  • 上海門戶網(wǎng)站制推薦友情鏈接
  • 湖南seo丈哥seo博客
  • 返利網(wǎng)站制作最新病毒感染
  • 網(wǎng)站標簽名詞搜索排名優(yōu)化軟件
  • 會python做網(wǎng)站seo優(yōu)化前景
  • 天長企業(yè)網(wǎng)站制作最近的新聞?wù)?/a>
  • 做賭石網(wǎng)站客服的經(jīng)驗電子商務(wù)seo實訓總結(jié)
  • 網(wǎng)站做短信接口具體方法正規(guī)的關(guān)鍵詞優(yōu)化軟件
  • 多用戶智能網(wǎng)站建設(shè)源碼洛陽網(wǎng)站seo
  • 聊城開發(fā)區(qū)建設(shè)局網(wǎng)站湖南專業(yè)關(guān)鍵詞優(yōu)化服務(wù)水平
  • 公務(wù)員 做網(wǎng)站 違法網(wǎng)站制作網(wǎng)站推廣
  • 手機網(wǎng)站改版公司百度關(guān)鍵詞熱度查詢工具