@openedx/frontend-base 1.0.0-alpha.32 → 1.0.0-alpha.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
1
  import { SiteConfig } from '../types';
2
- import './app.scss';
2
+ import './style';
3
3
  declare const siteConfig: SiteConfig;
4
4
  export default siteConfig;
@@ -1,7 +1,7 @@
1
1
  import { EnvironmentTypes } from '../types';
2
2
  import { devFooterApp, devHeaderApp, devHomeApp, devUserApp, slotShowcaseApp } from './dev';
3
3
  import { footerApp, headerApp, shellApp } from '.';
4
- import './app.scss';
4
+ import './style';
5
5
  const siteConfig = {
6
6
  apps: [
7
7
  shellApp,
@@ -1 +1 @@
1
- {"version":3,"file":"site.config.dev.js","sourceRoot":"","sources":["../../shell/site.config.dev.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAc,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAC5F,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC;AAEnD,OAAO,YAAY,CAAC;AAEpB,MAAM,UAAU,GAAe;IAC7B,IAAI,EAAE;QACJ,QAAQ;QACR,SAAS;QACT,SAAS;QACT,UAAU;QACV,UAAU;QACV,YAAY;QACZ,YAAY;QACZ,eAAe;KAChB;IAED,cAAc,EAAE;QACd;YACE,IAAI,EAAE,mCAAmC;YACzC,GAAG,EAAE,4CAA4C;SAClD;QACD;YACE,IAAI,EAAE,mCAAmC;YACzC,GAAG,EAAE,4CAA4C;SAClD;QACD;YACE,IAAI,EAAE,kCAAkC;YACxC,GAAG,EAAE,qCAAqC;SAC3C;KACF;IAED,UAAU;IACV,MAAM,EAAE,OAAO;IACf,QAAQ,EAAE,kBAAkB;IAC5B,OAAO,EAAE,mCAAmC;IAC5C,WAAW,EAAE,gBAAgB,CAAC,WAAW;IAEzC,gBAAgB;IAChB,QAAQ,EAAE,oCAAoC;IAC9C,SAAS,EAAE,qCAAqC;IAEhD,WAAW;IACX,UAAU,EAAE,8BAA8B;IAC1C,oBAAoB,EAAE,+BAA+B;CACtD,CAAC;AAEF,eAAe,UAAU,CAAC","sourcesContent":["import { EnvironmentTypes, SiteConfig } from '../types';\nimport { devFooterApp, devHeaderApp, devHomeApp, devUserApp, slotShowcaseApp } from './dev';\nimport { footerApp, headerApp, shellApp } from '.';\n\nimport './app.scss';\n\nconst siteConfig: SiteConfig = {\n apps: [\n shellApp,\n headerApp,\n footerApp,\n devUserApp,\n devHomeApp,\n devHeaderApp,\n devFooterApp,\n slotShowcaseApp,\n ],\n\n externalRoutes: [\n {\n role: 'org.openedx.frontend.role.profile',\n url: 'http://apps.local.openedx.io:1995/profile/'\n },\n {\n role: 'org.openedx.frontend.role.account',\n url: 'http://apps.local.openedx.io:1997/account/'\n },\n {\n role: 'org.openedx.frontend.role.logout',\n url: 'http://local.openedx.io:8000/logout'\n },\n ],\n\n // General\n siteId: 'shell',\n siteName: 'My Open edX Site',\n baseUrl: 'http://apps.local.openedx.io:8080',\n environment: EnvironmentTypes.DEVELOPMENT,\n\n // Frontend URLs\n loginUrl: 'http://local.openedx.io:8000/login',\n logoutUrl: 'http://local.openedx.io:8000/logout',\n\n // API URLs\n lmsBaseUrl: 'http://local.openedx.io:8000',\n runtimeConfigJsonUrl: '/api/frontend_site_config/v1/',\n};\n\nexport default siteConfig;\n"]}
1
+ {"version":3,"file":"site.config.dev.js","sourceRoot":"","sources":["../../shell/site.config.dev.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAc,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAC5F,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC;AAEnD,OAAO,SAAS,CAAC;AAEjB,MAAM,UAAU,GAAe;IAC7B,IAAI,EAAE;QACJ,QAAQ;QACR,SAAS;QACT,SAAS;QACT,UAAU;QACV,UAAU;QACV,YAAY;QACZ,YAAY;QACZ,eAAe;KAChB;IAED,cAAc,EAAE;QACd;YACE,IAAI,EAAE,mCAAmC;YACzC,GAAG,EAAE,4CAA4C;SAClD;QACD;YACE,IAAI,EAAE,mCAAmC;YACzC,GAAG,EAAE,4CAA4C;SAClD;QACD;YACE,IAAI,EAAE,kCAAkC;YACxC,GAAG,EAAE,qCAAqC;SAC3C;KACF;IAED,UAAU;IACV,MAAM,EAAE,OAAO;IACf,QAAQ,EAAE,kBAAkB;IAC5B,OAAO,EAAE,mCAAmC;IAC5C,WAAW,EAAE,gBAAgB,CAAC,WAAW;IAEzC,gBAAgB;IAChB,QAAQ,EAAE,oCAAoC;IAC9C,SAAS,EAAE,qCAAqC;IAEhD,WAAW;IACX,UAAU,EAAE,8BAA8B;IAC1C,oBAAoB,EAAE,+BAA+B;CACtD,CAAC;AAEF,eAAe,UAAU,CAAC","sourcesContent":["import { EnvironmentTypes, SiteConfig } from '../types';\nimport { devFooterApp, devHeaderApp, devHomeApp, devUserApp, slotShowcaseApp } from './dev';\nimport { footerApp, headerApp, shellApp } from '.';\n\nimport './style';\n\nconst siteConfig: SiteConfig = {\n apps: [\n shellApp,\n headerApp,\n footerApp,\n devUserApp,\n devHomeApp,\n devHeaderApp,\n devFooterApp,\n slotShowcaseApp,\n ],\n\n externalRoutes: [\n {\n role: 'org.openedx.frontend.role.profile',\n url: 'http://apps.local.openedx.io:1995/profile/'\n },\n {\n role: 'org.openedx.frontend.role.account',\n url: 'http://apps.local.openedx.io:1997/account/'\n },\n {\n role: 'org.openedx.frontend.role.logout',\n url: 'http://local.openedx.io:8000/logout'\n },\n ],\n\n // General\n siteId: 'shell',\n siteName: 'My Open edX Site',\n baseUrl: 'http://apps.local.openedx.io:8080',\n environment: EnvironmentTypes.DEVELOPMENT,\n\n // Frontend URLs\n loginUrl: 'http://local.openedx.io:8000/login',\n logoutUrl: 'http://local.openedx.io:8000/logout',\n\n // API URLs\n lmsBaseUrl: 'http://local.openedx.io:8000',\n runtimeConfigJsonUrl: '/api/frontend_site_config/v1/',\n};\n\nexport default siteConfig;\n"]}
@@ -0,0 +1,3 @@
1
+ import '@openedx/paragon/dist/core.min.css';
2
+ import '@openedx/paragon/dist/light.min.css';
3
+ import './style.scss';
@@ -0,0 +1,10 @@
1
+ /*
2
+ * Shell style manifest. Each import is a separate webpack module, which
3
+ * keeps Paragon's CSS and the shell's own SCSS as independent compilation
4
+ * units: the build pipeline wraps each in the `shell` cascade layer by
5
+ * resource path. See ADR 0008.
6
+ */
7
+ import '@openedx/paragon/dist/core.min.css';
8
+ import '@openedx/paragon/dist/light.min.css';
9
+ import './style.scss';
10
+ //# sourceMappingURL=style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.js","sourceRoot":"","sources":["../../shell/style.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,oCAAoC,CAAC;AAC5C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,cAAc,CAAC","sourcesContent":["/*\n * Shell style manifest. Each import is a separate webpack module, which\n * keeps Paragon's CSS and the shell's own SCSS as independent compilation\n * units: the build pipeline wraps each in the `shell` cascade layer by\n * resource path. See ADR 0008.\n */\nimport '@openedx/paragon/dist/core.min.css';\nimport '@openedx/paragon/dist/light.min.css';\nimport './style.scss';\n"]}
@@ -1,5 +1,4 @@
1
- @use "@openedx/paragon/dist/core.min.css";
2
- @use "@openedx/paragon/dist/light.min.css";
1
+ @layer paragon, shell, app, site, brand;
3
2
 
4
3
  .flex-basis-0 {
5
4
  flex-basis: 0 !important;
@@ -1,8 +1,2 @@
1
1
  import { RuleSetRule } from 'webpack';
2
- /**
3
- * There are a few things we need to do here.
4
- *
5
- * - We only want to use MiniCssExtractPlugin on dependencies in dev, but not on our source code.
6
- * - We only want CssNano in production.
7
- */
8
2
  export default function getStylesheetRule(mode: 'dev' | 'production'): RuleSetRule;
@@ -10,49 +10,87 @@ const mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plug
10
10
  const path_1 = __importDefault(require("path"));
11
11
  const postcss_custom_media_1 = __importDefault(require("postcss-custom-media"));
12
12
  const postcss_rtlcss_1 = __importDefault(require("postcss-rtlcss"));
13
- /**
13
+ const postcssWrapLayer_1 = __importDefault(require("./postcssWrapLayer"));
14
+ /*
15
+ * Resource matchers for each cascade layer.
16
+ * Order declared at the site level: `paragon, shell, app, site, brand` (later wins).
17
+ *
18
+ * - paragon: @openedx/paragon base styles. First so everything else can override.
19
+ * - shell: frontend-base shell styles.
20
+ * - app: catch-all for any other stylesheet pulled from node_modules.
21
+ * Keeps apps from clobbering site or brand overrides without requiring
22
+ * app packages to follow any naming convention or self-declaration.
23
+ * - site: the composing site's own source tree (anything outside node_modules).
24
+ * - brand: @openedx/brand-* packages, last so build-time brand matches the
25
+ * precedence of runtime brand CSS (which is injected unlayered via
26
+ * <link> tags and thus beats every layered rule).
27
+ */
28
+ const PARAGON_RESOURCE = /@openedx[\\/]paragon[\\/]/;
29
+ const SHELL_RESOURCE = /(@openedx[\\/]frontend-base|frontend-base[\\/]shell)[\\/]/;
30
+ const BRAND_RESOURCE = /@(open)?edx[\\/]brand(-[^\\/]+)?[\\/]/;
31
+ const NODE_MODULES = /[\\/]node_modules[\\/]/;
32
+ /*
14
33
  * There are a few things we need to do here.
15
34
  *
16
35
  * - We only want to use MiniCssExtractPlugin on dependencies in dev, but not on our source code.
17
36
  * - We only want CssNano in production.
37
+ * - Each resource class (paragon, shell, app, site, brand) is wrapped in its
38
+ * own cascade layer by a PostCSS plugin so the cascade order is
39
+ * `paragon, shell, app, site, brand`.
18
40
  */
19
41
  function getStylesheetRule(mode) {
42
+ return {
43
+ test: /(.scss|.css)$/,
44
+ oneOf: [
45
+ {
46
+ resource: PARAGON_RESOURCE,
47
+ // We need Paragon to not elide CSS: we have to be able to import it
48
+ // directly from shell/style.ts
49
+ sideEffects: true,
50
+ use: [
51
+ mini_css_extract_plugin_1.default.loader,
52
+ ...getStyleUseConfig(mode, 'paragon'),
53
+ ],
54
+ },
55
+ {
56
+ resource: SHELL_RESOURCE,
57
+ use: [
58
+ mini_css_extract_plugin_1.default.loader,
59
+ ...getStyleUseConfig(mode, 'shell'),
60
+ ],
61
+ },
62
+ {
63
+ resource: BRAND_RESOURCE,
64
+ use: [
65
+ mini_css_extract_plugin_1.default.loader,
66
+ ...getStyleUseConfig(mode, 'brand'),
67
+ ],
68
+ },
69
+ {
70
+ resource: { not: [NODE_MODULES] },
71
+ use: [
72
+ getFirstLoader(mode),
73
+ ...getStyleUseConfig(mode, 'site'),
74
+ ],
75
+ },
76
+ {
77
+ use: [
78
+ getFirstLoader(mode),
79
+ ...getStyleUseConfig(mode, 'app'),
80
+ ],
81
+ },
82
+ ],
83
+ };
84
+ }
85
+ function getFirstLoader(mode) {
86
+ // In dev we keep site/app styles in JS bundles so hot-reloading works;
87
+ // in production everything is extracted to CSS files.
20
88
  if (mode === 'production') {
21
- // In the production case, all files should go through MiniCssExtractPlugin.
22
- return {
23
- test: /(.scss|.css)$/,
24
- use: [
25
- mini_css_extract_plugin_1.default.loader,
26
- ...getStyleUseConfig(mode),
27
- ],
28
- };
29
- }
30
- else {
31
- // In the dev case, only our @openedx dependencies go through MiniCssExtractPlugin.
32
- // We are not extracting CSS from the javascript bundles in development because extracting
33
- // prevents hot-reloading from working, it increases build time, and we don't care about
34
- // flash-of-unstyled-content issues in development.
35
- return {
36
- test: /(.scss|.css)$/,
37
- oneOf: [
38
- {
39
- resource: /(@openedx\/paragon|@(open)?edx\/brand)/,
40
- use: [
41
- mini_css_extract_plugin_1.default.loader,
42
- ...getStyleUseConfig(mode),
43
- ],
44
- },
45
- {
46
- use: [
47
- require.resolve('style-loader'), // creates style nodes from JS strings
48
- ...getStyleUseConfig(mode),
49
- ],
50
- },
51
- ]
52
- };
89
+ return mini_css_extract_plugin_1.default.loader;
53
90
  }
91
+ return require.resolve('style-loader');
54
92
  }
55
- function getStyleUseConfig(mode) {
93
+ function getStyleUseConfig(mode, layer) {
56
94
  return [
57
95
  {
58
96
  loader: require.resolve('css-loader'), // translates CSS into CommonJS
@@ -71,7 +109,7 @@ function getStyleUseConfig(mode) {
71
109
  loader: require.resolve('postcss-loader'),
72
110
  options: {
73
111
  postcssOptions: {
74
- plugins: getPostCssLoaderPlugins(mode), // Different behavior for dev and production.
112
+ plugins: getPostCssLoaderPlugins(mode, layer),
75
113
  },
76
114
  },
77
115
  },
@@ -93,10 +131,7 @@ function getStyleUseConfig(mode) {
93
131
  },
94
132
  ];
95
133
  }
96
- /**
97
- * This exists just to conditionally include CssNano in production.
98
- */
99
- function getPostCssLoaderPlugins(mode) {
134
+ function getPostCssLoaderPlugins(mode, layer) {
100
135
  const plugins = [
101
136
  (0, autoprefixer_1.default)({
102
137
  remove: false, // Prevents removing vendor prefixes
@@ -108,5 +143,6 @@ function getPostCssLoaderPlugins(mode) {
108
143
  plugins.push((0, cssnano_1.default)());
109
144
  }
110
145
  plugins.push((0, postcss_custom_media_1.default)());
146
+ plugins.push((0, postcssWrapLayer_1.default)({ layer }));
111
147
  return plugins;
112
148
  }
@@ -0,0 +1,4 @@
1
+ import { Plugin } from 'postcss';
2
+ export default function postcssWrapLayer({ layer }: {
3
+ layer: string;
4
+ }): Plugin;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = postcssWrapLayer;
4
+ const postcss_1 = require("postcss");
5
+ /*
6
+ * Wraps every top-level rule in the stylesheet in a single `@layer <name> { ... }`
7
+ * block, so that downstream cascade-layer ordering applies uniformly to everything
8
+ * produced by this compilation unit.
9
+ *
10
+ * Nodes left at the root (not moved into the layer):
11
+ * - `@charset`, `@import`, `@use`, `@forward` (must stay at the top of a stylesheet)
12
+ * - `@layer` statements and blocks (already layered, or declaring layer order)
13
+ */
14
+ function postcssWrapLayer({ layer }) {
15
+ const keepAtTop = new Set(['charset', 'import', 'use', 'forward', 'layer']);
16
+ return {
17
+ postcssPlugin: 'postcss-wrap-layer',
18
+ Once(root) {
19
+ const layerRule = new postcss_1.AtRule({ name: 'layer', params: layer });
20
+ root.each(node => {
21
+ if (node.type === 'atrule' && keepAtTop.has(node.name)) {
22
+ return;
23
+ }
24
+ node.remove();
25
+ layerRule.append(node);
26
+ });
27
+ if (layerRule.nodes && layerRule.nodes.length > 0) {
28
+ root.append(layerRule);
29
+ }
30
+ },
31
+ };
32
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openedx/frontend-base",
3
- "version": "1.0.0-alpha.32",
3
+ "version": "1.0.0-alpha.33",
4
4
  "description": "Build tools, setup and config for frontend apps",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -9,7 +9,7 @@
9
9
  ".": "./dist/index.js",
10
10
  "./tools": "./dist/tools/index.js",
11
11
  "./tools/tsconfig.json": "./dist/tools/typescript/tsconfig.json",
12
- "./shell/app.scss": "./dist/shell/app.scss",
12
+ "./shell/style": "./dist/shell/style.js",
13
13
  "./shell/site": "./dist/shell/site.js"
14
14
  },
15
15
  "files": [
@@ -53,7 +53,8 @@
53
53
  },
54
54
  "sideEffects": [
55
55
  "*.css",
56
- "*.scss"
56
+ "*.scss",
57
+ "**/shell/style.{js,ts}"
57
58
  ],
58
59
  "homepage": "https://github.com/openedx/frontend-base#readme",
59
60
  "dependencies": {