Skip to content

Commit 33f800e

Browse files
committed
Upgrade css-loader
- Removed typings-for-css-modules-loader as this package is abandoned - Wrote a simple loader to replace typings-for-css-modules-loader that works with modern css-loader - The other typings packages suggested in Jimdo/typings-for-css-modules-loader#81 didn't work well (either involved too much change, or didn't work at all with current css-loader@3) - Our simple loader maintains the same output as the original loader
1 parent 3acdb96 commit 33f800e

File tree

6 files changed

+232
-187
lines changed

6 files changed

+232
-187
lines changed

server/webapp/WEB-INF/rails/package.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"shellwords-ts": "^2.0.4",
4343
"underscore.string": "^3.3.5",
4444
"url-parse": "^1.4.7",
45-
"uuid": "^3.3.2"
45+
"uuid": "^3.3.3"
4646
},
4747
"devDependencies": {
4848
"@babel/core": "^7.0.0",
@@ -70,7 +70,7 @@
7070
"@types/jasmine-ajax": "^3.1.40",
7171
"@types/jasmine-jquery": "^1.5.33",
7272
"@types/license-checker": "^25.0.0",
73-
"@types/lodash": "^4.14.136",
73+
"@types/lodash": "^4.14.137",
7474
"@types/mini-css-extract-plugin": "^0.8.0",
7575
"@types/mithril": "2.0.0",
7676
"@types/node": "^12.7.2",
@@ -84,7 +84,7 @@
8484
"babel-eslint": "^10.0.2",
8585
"babel-loader": "^8.0.0",
8686
"cache-loader": "^4.1.0",
87-
"css-loader": "^1.0.1",
87+
"css-loader": "^3.2.0",
8888
"eslint": "^6.1.0",
8989
"eslint-loader": "^2.2.1",
9090
"eslint-plugin-es5": "^1.4.1",
@@ -108,7 +108,7 @@
108108
"karma-junit-reporter": "^1.2.0",
109109
"karma-safari-launcher": "^1.0.0",
110110
"karma-sourcemap-loader": "^0.3.7",
111-
"license-checker": "^24.0.1",
111+
"license-checker": "^25.0.1",
112112
"mini-css-extract-plugin": "^0.8.0",
113113
"node-sass": "^4.12.0",
114114
"optimize-css-assets-webpack-plugin": "^5.0.3",
@@ -126,12 +126,11 @@
126126
"ts-node": "^8.3.0",
127127
"tslint": "^5.18.0",
128128
"typescript": "^3.5.3",
129-
"typings-for-css-modules-loader": "^1.7.0",
130129
"unused-files-webpack-plugin": "^3.4.0",
131130
"upath": "^1.1.2",
132131
"url-loader": "^2.1.0",
133132
"webpack": "^4.39.2",
134-
"webpack-build-notifier": "^1.0.3",
133+
"webpack-build-notifier": "^2.0.0-alpha.3",
135134
"webpack-cli": "^3.3.7"
136135
}
137136
}

server/webapp/WEB-INF/rails/webpack/config/loaders/css-loader.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,22 @@ export function getMiniCssExtractLoader(configOptions: ConfigOptions): webpack.R
2828
loader: configOptions.production ? MiniCssExtractPlugin.loader : "style-loader",
2929
},
3030
{
31-
loader: "typings-for-css-modules-loader", // translates CSS into CommonJS
31+
loader: path.resolve(__dirname, "type-declarations-for-css-modules.js"),
3232
options: {
33-
modules: true,
33+
banner: "// This file is automatically generated by typings-for-css-modules.\n// Please do not change this file!"
34+
}
35+
},
36+
{
37+
loader: "css-loader",
38+
options: {
39+
modules: {
40+
mode: "local",
41+
localIdentName: "[name]__[local]___[hash:base64:5]"
42+
},
3443
sourceMap: true,
35-
camelCase: true,
3644
importLoaders: 1,
37-
localIdentName: "[name]__[local]___[hash:base64:5]",
38-
namedExport: true,
39-
banner: "// This file is automatically generated by typings-for-css-modules.\n// Please do not change this file!"
45+
localsConvention: "camelCase",
46+
onlyLocals: false
4047
}
4148
},
4249
{
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright 2019 ThoughtWorks, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
const fs = require("fs");
18+
const os = require("os");
19+
const loaderUtils = require("loader-utils");
20+
const path = require("path");
21+
22+
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Reserved_keywords_as_of_ECMAScript_2015
23+
const RESERVED_WORDS = new Set([
24+
"break",
25+
"case",
26+
"catch",
27+
"class",
28+
"const",
29+
"continue",
30+
"debugger",
31+
"default",
32+
"delete",
33+
"do",
34+
"else",
35+
"export",
36+
"extends",
37+
"finally",
38+
"for",
39+
"function",
40+
"if",
41+
"import",
42+
"in",
43+
"instanceof",
44+
"new",
45+
"return",
46+
"super",
47+
"switch",
48+
"this",
49+
"throw",
50+
"try",
51+
"typeof",
52+
"var",
53+
"void",
54+
"while",
55+
"with",
56+
"yield"
57+
]);
58+
59+
const CSS_MODULE_KEY_RE = /"([^\\"]+)":/g;
60+
const WORD_ONLY_CHARS_RE = /^\w+$/i;
61+
62+
module.exports = function createTypeDeclarations(content, map, meta) {
63+
this.cacheable();
64+
const callback = this.async();
65+
66+
let typeDecls = "";
67+
const options = loaderUtils.getOptions(this) || {};
68+
69+
if (options.banner && "string" === typeof options.banner) {
70+
typeDecls += `${options.banner}\n`;
71+
}
72+
73+
const cssClassnames = [];
74+
75+
let match;
76+
77+
// content includes a huge payload which introduces extra/unwanted keys in the *.scss..d.ts
78+
// so we strip them out by focusing on the locals
79+
const locals = content.split("// Exports\nexports.locals = ").pop() || "";
80+
81+
while (match = CSS_MODULE_KEY_RE.exec(locals), !!match) {
82+
const key = match[1];
83+
84+
if (!cssClassnames.includes(key) && acceptName(key)) {
85+
cssClassnames.push(key);
86+
}
87+
}
88+
89+
for (const key of cssClassnames) {
90+
typeDecls += `export const ${key}: string;\n`;
91+
}
92+
93+
if ("" !== typeDecls) {
94+
fs.writeFile(typingsFilename(this.resourcePath), typeDecls.replace(/\n/g, os.EOL), { encoding: "utf-8", mode: 0o644 }, () => {
95+
callback(null, content, map, meta);
96+
});
97+
} else {
98+
callback(null, content, map, meta);
99+
}
100+
};
101+
102+
function acceptName(key) {
103+
return !RESERVED_WORDS.has(key) && WORD_ONLY_CHARS_RE.test(key);
104+
}
105+
106+
function typingsFilename(filename) {
107+
const dir = path.dirname(filename);
108+
const name = path.basename(filename);
109+
return path.join(dir, `${name}.d.ts`);
110+
}

server/webapp/WEB-INF/rails/webpack/helpers/hack-font.scss

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,28 @@
1717
@import "../views/global/common";
1818

1919
@include font-face($font-family: "Hack",
20-
$file-path: "hack-font/build/web/fonts/hack-regular",
20+
$file-path: "~hack-font/build/web/fonts/hack-regular",
2121
$file-formats: ("woff2", "woff")) {
2222
font-weight: 400;
2323
font-style: normal;
2424
}
2525

2626
@include font-face($font-family: "Hack",
27-
$file-path: "hack-font/build/web/fonts/hack-bold",
27+
$file-path: "~hack-font/build/web/fonts/hack-bold",
2828
$file-formats: ("woff2", "woff")) {
2929
font-weight: 700;
3030
font-style: normal;
3131
}
3232

3333
@include font-face($font-family: "Hack",
34-
$file-path: "hack-font/build/web/fonts/hack-italic",
34+
$file-path: "~hack-font/build/web/fonts/hack-italic",
3535
$file-formats: ("woff2", "woff")) {
3636
font-weight: 400;
3737
font-style: italic;
3838
}
3939

4040
@include font-face($font-family: "Hack",
41-
$file-path: "hack-font/build/web/fonts/hack-bolditalic",
41+
$file-path: "~hack-font/build/web/fonts/hack-bolditalic",
4242
$file-formats: ("woff2", "woff")) {
4343
font-weight: 700;
4444
font-style: italic;

server/webapp/WEB-INF/rails/webpack/helpers/spa_base.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
}
3434

3535
@include font-face($font-family: 'FontAwesome',
36-
$file-path: 'font-awesome/fonts/fontawesome-webfont',
36+
$file-path: '~font-awesome/fonts/fontawesome-webfont',
3737
$file-formats: ("woff2", "woff", "ttf", "svg", "eot")) {
3838
font-weight: normal;
3939
font-style: normal;
@@ -85,7 +85,7 @@ $opensans-variants: (
8585
@each $variant-name in map-keys($opensans-variants) {
8686
$variant: map-get($opensans-variants, $variant-name);
8787
@include font-face($font-family: 'Open Sans',
88-
$file-path: 'opensans/OpenSans-#{$variant-name}-webfont',
88+
$file-path: '~opensans/OpenSans-#{$variant-name}-webfont',
8989
$file-formats: ("eot", "woff", "ttf")
9090
) {
9191
font-style: map-get($variant, 'font-style');

0 commit comments

Comments
 (0)