[英]Lazy load application theme styles with Angular CLI
我正在嘗試切換<link />
的href
以進行主題化,並且 SCSS 主題位於我的 monorepo 的包文件夾中,這些文件夾在 node_modules 中進行了node_modules
。 我需要能夠編譯和引用這些。
我遇到了以下固定問題: angular/angular-cli#3401並且一直在嘗試實現類似的東西:
"styles": [
"styles.scss",
{
"input": "../node_modules/@org/themes/dark.scss",
"output": "dark",
"lazy": true
}
],
我的理解(可能不正確)是這會將dark.scss
文件編譯為dist/dark.bundle.css
並且我可以通過http://localhost:4200/dist/dark.bundle.css加載它但是它沒有按預期工作。 我是誤解了什么還是這樣做完全錯誤?
如何從node_modules
編譯一個 SCSS 文件,然后我可以在應用程序中延遲加載? 我可以嘗試另一種/更好的方法嗎?
附加說明:
4.2.4
1.3.0
版node_modules/@org/themes
是一個符號鏈接ng serve --preserve-symlinks
選項以防上述問題。 它沒有任何區別我已經研究了Angular Material 文檔網站解決這個問題的方式,似乎他們有一個自定義構建腳本,可以在為應用程序提供服務之前將 SCSS 文件編譯為assets
目錄中的 CSS 文件。 我認為上面的固定問題消除了這一步的需要,但也許不是。 這是唯一可以做到的方法嗎?
感謝@Kuncevic。 我錯過了--extract-css
標志。
工作配置:
"styles": [
"styles.scss",
{
"input": "../node_modules/@org/themes/src/dark.scss",
"output": "themes/dark",
"lazy": true
}
],
使用以下服務腳本,我可以通過http://localhost:4200/themes/dark.bundle.css訪問它:
ng serve --extract-css --preserve-symlinks
通過設置"lazy": true
意味着它不會出現在index.html
但沒有機制可以為您延遲加載該包,請檢查該評論:
lazy 選項實際上不會延遲加載任何東西。 它只是阻止它在應用程序啟動時執行。
我同意"lazy": true
起初有點令人困惑。
如果您運行ng build
您實際上可以看到構建中輸出的內容並分析 cli 生成的所有文件。
當你這樣做時:
{
"input": "../node_modules/@org/themes/dark.scss",
"output": "dark",
"lazy": true
}
您應該能夠直接在http://localhost:4200/dark.bundle.js上訪問您的文件,但是當您設置"lazy": true
它不會出現在index.html
中"lazy": true
如果你想在開發模式下獲得
dark.bundle.css
包而不是dark.bundle.js
,你可以使用--extract-css
標志。
cli 之所以在 dev 模式下將樣式生成到js
bundle 中,是因為這種方式要快得多。 Bud 當你像ng buld --prod
那樣做 prod 構建時,它會默認輸出到.css
。
我知道這是一篇舊帖子,但我還沒有找到一個完整的例子,只是片段來在 Angular 中為CSS 文件或js 文件實現延遲加載。 這是 Angular 7.1.4 版本和font-awesome 4.7和bootstrap 4延遲加載的解決方案
npm install --save font-awesome bootstrap
編輯angular.json文件以確保編譯器將生成分離的文件到dist文件夾中
"styles": [ "src/styles.css", { "input": "./node_modules/font-awesome/css/font-awesome.css", "lazy": true, "bundleName": "font-awesome" }, { "input": "./node_modules/bootstrap/dist/css/bootstrap.min.css", "lazy": true, "bundleName": "bootstrap" } ],
參數說明:
"input" : "第一步中的命令將下載引導程序和字體的位置"
"lazy" : " true的值將確保編譯器不會將bootstrap.min.css和font-awesome.css文件嵌入到發送到瀏覽器的編譯文件中"
"bundleName" : "是您將在dist文件夾中找到的名稱"
<base href="/">
下的標頭標記內添加以下腳本到index.html <script>
window.onload = function () {
function loadScript(scriptUrl) {
const script = document.createElement('script');
script.src = scriptUrl;
document.body.appendChild(script);
}
loadScript('font-awesome.js');
loadScript('bootstrap.js');
}
</script>
注意: window.onload = function ()
用於確保頁面被加載(這是因為我們進入dist的文件是.js格式;這是Angular編譯的快捷方式)
ng build --extract-css=false --prod
注意:在構建時我們使用--extract-css=false來生成.js文件
測試
您必須能夠看到 bootstrap.js 和 font-awesome.js 像照片中一樣分別加載,並且您還可以看到沒有樣式的頁面=> 這是樣式加載良好的時刻DOM 加載后
對於任何想要在 .angular-cli.json 延遲加載而沒有哈希的情況下使用全局 css scipts 的人,我編寫了以下腳本(例如 patch-ng-cli.js)
const fs = require('fs');
const stylesFileToPatch = "node_modules/@angular/cli/models/webpack-configs/styles.js";
const regex = /extraPlugins\.push\(.*\}\)\)\;/;
const patchContent = `
// PATCHED CONTENT START
const globalStyles = utils_1.extraEntryParser(appConfig.styles, appRoot, 'styles');
extraPlugins.push(new ExtractTextPlugin({ filename: getPath => {
const generatedFileName = getPath(\`[name]\${hashFormat.extract}.bundle.css\`);
const name = generatedFileName.split(".")[0];
const globalAppStylesConfigEntry = globalStyles.find(path => path.output === name);
if (globalAppStylesConfigEntry && globalAppStylesConfigEntry.lazy){
console.log(\`\${name} will not be hashed due to lazy loading\`);
return \`\${name}.bundle.css\`
}
console.log(generatedFileName);
return generatedFileName;
}}));
// PATCHED CONTENT END
`;
fs.readFile(stylesFileToPatch, (err, data) => {
if (err) { throw err; }
const text = data.toString();
const isAlreadyPatched = !!text.match("PATCHED CONTENT");
if (isAlreadyPatched) return console.warn("-- already patched --", stylesFileToPatch);
console.log('-- Patching ng-cli: ', stylesFileToPatch);
const patchedContent = text.replace(regex, patchContent);
const file = fs.openSync(stylesFileToPatch, 'r+');
fs.writeFile(file, patchedContent, () => console.log("-- Patching -- OK"));
fs.close(file);
});
然后在 npm install 之后通過 package.json 中的 npm 腳本運行這個腳本
"postinstall": "node ./patch-ng-cli.js",
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.