Lazy loading application style themes using Angular CLI

I am trying to switch href for <link /> for topic purposes, and SCSS themes are in the package folder of my monorepo, which are symbolically linked in node_modules . I need to be able to compile and reference them.

I ran into the following problem: angular / angular-cli # 3401 and tried to implement something like this:

 "styles": [ "styles.scss", { "input": "../node_modules/@org/themes/dark.scss", "output": "dark", "lazy": true } ], 

My understanding (possibly incorrect) was that this would compile the dark.scss file into dist/dark.bundle.css and that I could download it via http: // localhost: 4200 / dist / dark.bundle.css , but it does not work as expected. Am I not understanding something or am I doing this completely wrong?

How can I compile the SCSS file from node_modules , which I can then use in the application? Is there any other / better approach I could try instead?

Additional notes:

  • Using Angular version 4.2.4
  • Using Angular CLI Version 1.3.0
  • documentation for this approach
  • I work in monorepo, so node_modules/@org/themes is a symbolic link
  • I tried using the ng serve --preserve-symlinks option ng serve --preserve-symlinks in case the problem was higher. It didnโ€™t matter.

I looked at the way the Angular docs Content Site approaches this issue , and it seems like they have a custom build script that compiles SCSS files into CSS files in the assets directory before serving the application. I thought the fixed issue above eliminates the need for this step, but maybe not. Is this the only way to do this?

solvable

Thanks @Kuncevic. I was missing the flag --extract-css .

Working configuration:

 "styles": [ "styles.scss", { "input": "../node_modules/@org/themes/src/dark.scss", "output": "themes/dark", "lazy": true } ], 

And with the following script service, I can access it through http: // localhost: 4200 / themes / dark.bundle.css :

ng serve --extract-css --preserve-symlinks

+5
source share
2 answers

Setting "lazy": true means that it will not be displayed in index.html , but there is no mechanism that will be lazy loading this package for you, make sure comment :

the lazy option is not really lazy. It simply prevents it from starting when the application starts.

I agree "lazy": true at first a little confused.

If you run ng build , you can see what will be displayed in your assembly and analyze all the files created by cli.

When you do:

 { "input": "../node_modules/@org/themes/dark.scss", "output": "dark", "lazy": true } 

You should have access to your file directly in http: // localhost: 4200 / dark.bundle.js , but it will not appear in index.html when installing "lazy": true

If you want to get the dark.bundle.css package instead of dark.bundle.js in dev mode, you can use the --extract-css flag.

The reason cli generates styles in js bundle in dev mode is because this method is much faster. Bad, when you create prod, like ng buld --prod , by default it will be output to .css .

+3
source

For those who want to use global css scripts in .angular-cli.json, lazy, loaded without a hash, I wrote the following script (e.g. 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); }); 

Then run this script after installing npm through npm scripts in package.json

 "postinstall": "node ./patch-ng-cli.js", 
0
source

Source: https://habr.com/ru/post/1271683/


All Articles