diff --git a/apps/elements/project.json b/apps/elements/project.json index 83f2d40..58eea97 100644 --- a/apps/elements/project.json +++ b/apps/elements/project.json @@ -11,7 +11,7 @@ "customWebpackConfig": { "libraryTarget": "system", "excludeAngularDependencies": true, - "path": "apps/elements/webpack.config.ts" + "path": "apps/elements/webpack.config.js" }, "outputPath": "dist/apps/elements", "index": "apps/elements/src/index.html", diff --git a/apps/elements/src/main.scss b/apps/elements/src/main.scss new file mode 100644 index 0000000..c2e5f05 --- /dev/null +++ b/apps/elements/src/main.scss @@ -0,0 +1,3 @@ +body.this-class-is-for-e2e-testing { + background-color: red; +} diff --git a/apps/elements/src/main.single-spa.ts b/apps/elements/src/main.single-spa.ts index 812543f..19b262a 100644 --- a/apps/elements/src/main.single-spa.ts +++ b/apps/elements/src/main.single-spa.ts @@ -5,16 +5,29 @@ import { enableProdMode, getSingleSpaExtraProviders } from 'single-spa-angular'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; +// @ts-ignore +import unmountableStyles from './main.scss?unmountable'; + if (environment.production) { enableProdMode(); } const lifecycles = singleSpaAngularElements({ template: '', - bootstrapFunction: () => - platformBrowserDynamic(getSingleSpaExtraProviders()).bootstrapModule(AppModule, { - ngZone: 'noop', - }), + bootstrapFunction: async () => { + unmountableStyles.use(); + + const ngModuleRef = await platformBrowserDynamic(getSingleSpaExtraProviders()).bootstrapModule( + AppModule, + { + ngZone: 'noop', + }, + ); + + ngModuleRef.onDestroy(() => unmountableStyles.unuse()); + + return ngModuleRef; + }, }); export const bootstrap = lifecycles.bootstrap; diff --git a/apps/elements/webpack.config.js b/apps/elements/webpack.config.js new file mode 100644 index 0000000..925fca6 --- /dev/null +++ b/apps/elements/webpack.config.js @@ -0,0 +1,26 @@ +const singleSpaConfig = require('../../lib/lib/webpack'); + +module.exports = (config, options) => { + config = singleSpaConfig.default(config, options); + + // https://github.com/angular/angular-cli/blob/b65ef44cbe36416271521eba0ba5fc0b4442af55/packages/angular_devkit/build_angular/src/tools/webpack/configs/styles.ts#L235-L255 + const scssRule = config.module.rules.find(rule => rule.test.toString().includes('scss')).rules[0]; + + scssRule.oneOf.unshift({ + resourceQuery: /\?unmountable/, + use: [ + { + loader: 'style-loader', + options: { + injectType: 'lazySingletonStyleTag', + }, + }, + // Take the other loaders that Angular uses internally. + // Since we replaced the `mini-css-extract-plugin` loader with the + // `style-loader` (which is at index 0), we slice the list by 1 index. + ...scssRule.oneOf[0].use.slice(1), + ], + }); + + return config; +}; diff --git a/apps/elements/webpack.config.ts b/apps/elements/webpack.config.ts deleted file mode 100644 index a61bc24..0000000 --- a/apps/elements/webpack.config.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from '../../libs/single-spa-angular/webpack'; diff --git a/cypress/integration/elements.spec.js b/cypress/integration/elements.spec.js index eade7cd..3dc712c 100644 --- a/cypress/integration/elements.spec.js +++ b/cypress/integration/elements.spec.js @@ -30,4 +30,17 @@ describe('Custom element application', () => { ); }); }); + + describe('https://github.com/single-spa/single-spa-angular/issues/502', () => { + it('should navigate to /elements, inject