[英]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.