Skip to content

Commit

Permalink
chore: add unmountable CSS example (#528)
Browse files Browse the repository at this point in the history
  • Loading branch information
arturovt authored Sep 21, 2024
1 parent d1c2d1d commit e247aac
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 6 deletions.
2 changes: 1 addition & 1 deletion apps/elements/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions apps/elements/src/main.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
body.this-class-is-for-e2e-testing {
background-color: red;
}
21 changes: 17 additions & 4 deletions apps/elements/src/main.single-spa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: '<elements-root />',
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;
Expand Down
26 changes: 26 additions & 0 deletions apps/elements/webpack.config.js
Original file line number Diff line number Diff line change
@@ -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;
};
1 change: 0 additions & 1 deletion apps/elements/webpack.config.ts

This file was deleted.

13 changes: 13 additions & 0 deletions cypress/integration/elements.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 <style> and remove it, when navigated to /', () => {
cy.visit('/').visit('/elements');

// See `apps/elements/src/main.scss`.
cy.get('style').should('contain.text', 'body.this-class-is-for-e2e-testing');

cy.visit('/');

cy.get('style').should('not.contain.text', 'body.this-class-is-for-e2e-testing');
});
});
});

0 comments on commit e247aac

Please sign in to comment.