forked from openedx/frontend-base
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgetStylesheetRule.ts
More file actions
111 lines (106 loc) · 3.36 KB
/
Copy pathgetStylesheetRule.ts
File metadata and controls
111 lines (106 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import PostCssAutoprefixerPlugin from 'autoprefixer';
import CssNano from 'cssnano';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import path from 'path';
import PostCssCustomMediaCSS from 'postcss-custom-media';
import PostCssRTLCSS from 'postcss-rtlcss';
import { RuleSetRule } from 'webpack';
/**
* There are a few things we need to do here.
*
* - We only want to use MiniCssExtractPlugin on dependencies in dev, but not on our source code.
* - We only want CssNano in production.
*/
export default function getStylesheetRule(mode: 'dev' | 'production'): RuleSetRule {
if (mode === 'production') {
// In the production case, all files should go through MiniCssExtractPlugin.
return {
test: /(.scss|.css)$/,
use: [
MiniCssExtractPlugin.loader,
...getStyleUseConfig(mode),
],
};
} else {
// In the dev case, only our @openedx dependencies go through MiniCssExtractPlugin.
// We are not extracting CSS from the javascript bundles in development because extracting
// prevents hot-reloading from working, it increases build time, and we don't care about
// flash-of-unstyled-content issues in development.
return {
test: /(.scss|.css)$/,
oneOf: [
{
resource: /(@openedx\/paragon|@(open)?edx\/brand)/,
use: [
MiniCssExtractPlugin.loader,
...getStyleUseConfig(mode),
],
},
{
use: [
require.resolve('style-loader'), // creates style nodes from JS strings
...getStyleUseConfig(mode),
],
},
]
};
}
}
function getStyleUseConfig(mode: 'dev' | 'production') {
return [
{
loader: require.resolve('css-loader'), // translates CSS into CommonJS
options: {
sourceMap: true,
modules: {
// namedExport defaults to true in css-loader v7, but we rely on the old behavior.
// Details here:
// https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md#700-2024-04-04
namedExport: false,
mode: 'icss',
},
},
},
{
loader: require.resolve('postcss-loader'),
options: {
postcssOptions: {
plugins: getPostCssLoaderPlugins(mode), // Different behavior for dev and production.
},
},
},
require.resolve('resolve-url-loader'),
{
loader: require.resolve('sass-loader'), // compiles Sass to CSS
options: {
sourceMap: true,
sassOptions: {
includePaths: [
path.join(process.cwd(), 'node_modules'),
path.join(process.cwd(), 'src'),
],
// Silences compiler deprecation warnings. They mostly come from bootstrap and/or paragon.
quietDeps: true,
silenceDeprecations: ['abs-percent', 'color-functions', 'import', 'global-builtin', 'legacy-js-api'],
},
},
},
];
}
/**
* This exists just to conditionally include CssNano in production.
*/
function getPostCssLoaderPlugins(mode: 'dev' | 'production') {
const plugins: any[] = [
PostCssAutoprefixerPlugin({
remove: false, // Prevents removing vendor prefixes
}),
PostCssRTLCSS(),
];
// We want CSSNano third, and only in production.
if (mode === 'production') {
plugins.push(CssNano());
}
plugins.push(PostCssCustomMediaCSS());
return plugins;
}