Skip to content

Commit f1c6aeb

Browse files
committed
Extend Node.js support to include ^10
1 parent 2f9b96c commit f1c6aeb

File tree

6 files changed

+128
-83
lines changed

6 files changed

+128
-83
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ jobs:
4343
matrix:
4444
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
4545
node_version:
46+
- 10
4647
- 12.20.0
4748
- 14.13.0
4849
- 16
@@ -56,6 +57,7 @@ jobs:
5657
cache: "npm"
5758
- run: npm ci
5859
- run: npm run test
60+
if: ${{ matrix.node_version != '10' }}
5961
- run: npm run esm-to-cjs-and-test
6062

6163
- run: npm run coverage

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## next
22

3+
- Extended Node.js support to include `^10`
34
- Fixed `main` field in `package.json` to refer to CommonJS module
45
- Bumped `css-tree` to `~2.0.4` (fixed CSS serialization issue in IE11)
56

@@ -13,7 +14,7 @@
1314

1415
- Added support for [CSS Selectors Level 4](https://www.w3.org/TR/selectors-4/) and legacy pseudos in specificity calculation, i.e. `:has()`, `:not(<selector-list>)`, `:is()`, `:matches()`, `:-moz-any()`, `:-webkit-any()`, `:where()`, `:nth-child(... of <selector-list>)` and `:nth-last-child(... of <selector-list>)`
1516
- Package
16-
- Changed supported versions of Node.js to `^12.20.0`, `^14.13.0` and `>=15.0.0`
17+
- Changed supported versions of Node.js to `^12.20.0`, `^14.13.0` and `>=15.0.0` (extended in `5.0.2` to include `^10`)
1718
- Converted to ES modules. However, CommonJS is supported as well (dual module)
1819
- Changed bundle set to provide `dist/csso.js` (an IIFE version with `csso` as a global name) and `dist/csso.esm.js` (as ES module). Both are minified
1920
- Bumped `css-tree` to [`2.0`](https://github.com/csstree/csstree/releases/tag/v2.0.0)

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"build-and-test": "npm run build && npm run test:dist && npm run test:cjs",
5252
"bundle": "node scripts/bundle",
5353
"bundle-and-test": "npm run bundle && npm run test:dist",
54-
"esm-to-cjs": "node scripts/esm-to-cjs",
54+
"esm-to-cjs": "node scripts/esm-to-cjs.cjs",
5555
"esm-to-cjs-and-test": "npm run esm-to-cjs && npm run test:cjs",
5656
"coverage": "c8 --reporter=lcovonly npm test",
5757
"prepublishOnly": "npm run lint-and-test && npm run build-and-test",
@@ -69,7 +69,7 @@
6969
"source-map-js": "^1.0.1"
7070
},
7171
"engines": {
72-
"node": "^12.20.0 || ^14.13.0 || >=15.0.0",
72+
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
7373
"npm": ">=7.0.0"
7474
},
7575
"files": [

scripts/esm-to-cjs.cjs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// This script is written using CommonJS since it should run
2+
// on Node.js versions which don't support for ESM
3+
4+
const fs = require('fs');
5+
const path = require('path');
6+
const { rollup } = require('rollup');
7+
8+
const { name: packageName } = require('../package.json');
9+
10+
const external = [
11+
'module',
12+
'fs',
13+
'path',
14+
'url',
15+
'assert',
16+
'json-to-ast',
17+
'css-tree',
18+
'csso',
19+
/^source-map/
20+
];
21+
22+
function removeCreateRequire(id) {
23+
return fs.readFileSync(id, 'utf8')
24+
.replace(/import .+ from 'module';/, '')
25+
.replace(/const require = .+;/, '');
26+
}
27+
28+
function replaceContent(map) {
29+
return {
30+
name: 'file-content-replacement',
31+
load(id) {
32+
const key = path.relative('', id);
33+
34+
if (map.hasOwnProperty(key)) {
35+
return map[key](id);
36+
}
37+
}
38+
};
39+
}
40+
41+
function patchTests() {
42+
// If Node.js doesn't support for `exports` it doesn't support for import/require
43+
// by package name inside the package itself, so this resolving will fail.
44+
// We can't use just `require(packageName)` here since CJS modules are not generated yet,
45+
// and Node.js will fail on resolving it either disregarding of `exports` support.
46+
// In this case we need to replace import/require using a package name with
47+
// a relative path to a module.
48+
try {
49+
require(`${packageName}/package.json`);
50+
return;
51+
} catch (e) {}
52+
53+
const pathToIndex = path.resolve(__dirname, '../cjs/index.cjs');
54+
55+
// Make replacement for relative path only for tests since we need to check everything
56+
// is work on old Node.js version. The rest of code should be unchanged since will run
57+
// on any Node.js version.
58+
console.log(`Fixing CommonJS tests by replacing "${packageName}" for a relative paths`);
59+
60+
return {
61+
name: 'cjs-tests-fix',
62+
resolveId(source) {
63+
if (/^..\/cjs/.test(source)) {
64+
return { id: source, external: true };
65+
}
66+
return null;
67+
},
68+
transform(code, id) {
69+
return code.replace(
70+
new RegExp(`from (['"])${packageName}\\1;`, 'g'),
71+
`from '${path.relative(path.dirname(id), pathToIndex)}'`
72+
);
73+
}
74+
};
75+
}
76+
77+
function readDir(dir) {
78+
return fs.readdirSync(dir)
79+
.filter(fn => fn.endsWith('.js'))
80+
.map(fn => `${dir}/${fn}`);
81+
}
82+
83+
async function build(outputDir, patch, ...entryPoints) {
84+
const startTime = Date.now();
85+
86+
console.log();
87+
console.log(`Convert ESM to CommonJS (output: ${outputDir})`);
88+
89+
const res = await rollup({
90+
external,
91+
input: entryPoints,
92+
plugins: [
93+
replaceContent({
94+
'lib/version.js': removeCreateRequire
95+
}),
96+
patch && patchTests()
97+
]
98+
});
99+
await res.write({
100+
dir: outputDir,
101+
entryFileNames: '[name].cjs',
102+
format: 'cjs',
103+
exports: 'auto',
104+
preserveModules: true,
105+
interop: false,
106+
esModule: false,
107+
generatedCode: {
108+
constBindings: true
109+
}
110+
});
111+
await res.close();
112+
113+
console.log(`Done in ${Date.now() - startTime}ms`);
114+
}
115+
116+
async function buildAll() {
117+
await build('./cjs', false, 'lib/index.js');
118+
await build('./cjs-test', true, ...readDir('test'));
119+
}
120+
121+
buildAll();

scripts/esm-to-cjs.js

Lines changed: 0 additions & 79 deletions
This file was deleted.

0 commit comments

Comments
 (0)