Skip to content

Commit af246be

Browse files
committed
fix: revert ESM dynamic import, require less >= 4.6.3
less@4.6.3 ships a pre-built CJS bundle (dist/less-node.cjs) and maps the "require" exports condition to it, resolving the ESM/CJS interop issue that prompted the dynamic import workaround in #578. Revert getLessImplementation back to synchronous require() and restore the standard test:only script. Update peer dependency to require less >= 4.6.3 on the 4.x line. Source map improvements introduced in #578 (sourceMapBasepath, disableSourcemapAnnotation, normalizeSourceMap) are preserved.
1 parent 5c452b5 commit af246be

12 files changed

Lines changed: 87 additions & 109 deletions

babel.config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ module.exports = (api) => {
1212
targets: {
1313
node: "18.12.0",
1414
},
15-
exclude: ["transform-dynamic-import"],
1615
},
1716
],
1817
],

package-lock.json

Lines changed: 7 additions & 7 deletions
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
@@ -38,7 +38,7 @@
3838
"fix:js": "npm run lint:js -- --fix",
3939
"fix:prettier": "npm run lint:prettier -- --write",
4040
"fix": "npm-run-all -l fix:js fix:prettier",
41-
"test:only": "node --experimental-vm-modules node_modules/jest-cli/bin/jest.js",
41+
"test:only": "cross-env NODE_ENV=test jest",
4242
"test:watch": "npm run test:only -- --watch",
4343
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
4444
"pretest": "npm run lint",
@@ -61,7 +61,7 @@
6161
"eslint-config-webpack": "^4.5.1",
6262
"husky": "^9.1.3",
6363
"jest": "^30.0.0",
64-
"less": "^4.6.2",
64+
"less": "^4.6.3",
6565
"less-plugin-glob": "^3.0.0",
6666
"lint-staged": "^15.2.7",
6767
"memfs": "^4.9.3",

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ async function lessLoader(source) {
1515
let implementation;
1616

1717
try {
18-
implementation = await getLessImplementation(this, options.implementation);
18+
implementation = getLessImplementation(this, options.implementation);
1919
} catch (error) {
2020
callback(error);
2121

src/utils.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,19 +223,20 @@ function normalizeSourceMap(map) {
223223

224224
newMap.sourceRoot = "";
225225

226-
// `less` (old versions) returns POSIX paths, that's why we need to transform them back to native paths.
226+
// `less` returns POSIX paths, that's why we need to transform them back to native paths.
227+
227228
newMap.sources = newMap.sources.map((source) => path.normalize(source));
228229

229230
return newMap;
230231
}
231232

232-
async function getLessImplementation(loaderContext, implementation) {
233+
function getLessImplementation(loaderContext, implementation) {
233234
let resolvedImplementation = implementation;
234235

235236
if (!implementation || typeof implementation === "string") {
236237
const lessImplPkg = implementation || "less";
237238

238-
resolvedImplementation = (await import(lessImplPkg)).default;
239+
resolvedImplementation = require(lessImplPkg);
239240
}
240241

241242
return resolvedImplementation;

test/__snapshots__/sourceMap-options.test.js.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ exports[`"sourceMap" options should generate source maps when value has "false"
4848
#it-works {
4949
margin: 10px;
5050
}
51-
"
51+
/*# sourceMappingURL=source-map.css.map */"
5252
`;
5353

5454
exports[`"sourceMap" options should generate source maps when value has "false" value, but the "lessOptions.sourceMap.outputSourceFiles" is "true": errors 1`] = `[]`;
@@ -60,8 +60,8 @@ exports[`"sourceMap" options should generate source maps when value has "false"
6060
"names": [],
6161
"sourceRoot": "",
6262
"sources": [
63-
"test/fixtures/node_modules/some/module.less",
64-
"test/fixtures/source-map.less",
63+
"node_modules/some/module.less",
64+
"source-map.less",
6565
],
6666
"sourcesContent": [
6767
".modules-dir-some-module {
Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,36 @@
11
import path from "path";
2+
import less from "less";
23

3-
export default async () => {
4-
const less = (await import("less")).default;
5-
6-
class Plugin extends less.FileManager {
7-
supports(filename) {
8-
if (filename === 'forFileLoaderPluginResolve.less') {
9-
return true;
10-
}
11-
12-
if (filename === "https://fonts.googleapis.com/css?family=Roboto:500") {
13-
return true;
14-
}
15-
16-
return false;
4+
class Plugin extends less.FileManager {
5+
supports(filename) {
6+
if (filename === 'forFileLoaderPluginResolve.less') {
7+
return true;
8+
}
9+
10+
if (filename === "https://fonts.googleapis.com/css?family=Roboto:500") {
11+
return true;
1712
}
1813

19-
loadFile(filename, ...args) {
20-
let result;
21-
22-
if (filename === 'forFileLoaderPluginResolve.less') {
23-
result = path.resolve(__dirname, '../', 'file-load-replacement.less');
24-
} else if (filename === "https://fonts.googleapis.com/css?family=Roboto:500") {
25-
result = path.resolve(__dirname, '../', 'mock-fonts.less');
26-
}
27-
28-
return super.loadFile(result, ...args);
29-
};
14+
return false;
3015
}
3116

32-
class CustomFileLoaderPlugin {
33-
install(less, pluginManager) {
34-
pluginManager.addFileManager(new Plugin());
17+
loadFile(filename, ...args) {
18+
let result;
19+
20+
if (filename === 'forFileLoaderPluginResolve.less') {
21+
result = path.resolve(__dirname, '../', 'file-load-replacement.less');
22+
} else if (filename === "https://fonts.googleapis.com/css?family=Roboto:500") {
23+
result = path.resolve(__dirname, '../', 'mock-fonts.less');
3524
}
25+
26+
return super.loadFile(result, ...args);
27+
};
28+
}
29+
30+
class CustomFileLoaderPlugin {
31+
install(less, pluginManager) {
32+
pluginManager.addFileManager(new Plugin());
3633
}
34+
}
3735

38-
return CustomFileLoaderPlugin;
39-
};
36+
module.exports = CustomFileLoaderPlugin;

test/helpers/getCodeFromLess.js

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import fs from "node:fs";
22
import path from "node:path";
33

4+
import less from "less";
5+
46
const pathMap = {
57
"some/css.css": path.resolve(
68
__dirname,
@@ -141,6 +143,37 @@ const pathMap = {
141143
"3rd/b.less": path.resolve(__dirname, "..", "fixtures", "3rd", "b.less"),
142144
};
143145

146+
class ResolvePlugin extends less.FileManager {
147+
supports(filename) {
148+
if (filename[0] === "/" || path.win32.isAbsolute(filename)) {
149+
return true;
150+
}
151+
152+
if (this.isPathAbsolute(filename)) {
153+
return false;
154+
}
155+
156+
return true;
157+
}
158+
159+
supportsSync() {
160+
return false;
161+
}
162+
163+
async loadFile(filename, ...args) {
164+
const result =
165+
pathMap[filename] || path.resolve(__dirname, "..", "fixtures", filename);
166+
167+
return super.loadFile(result, ...args);
168+
}
169+
}
170+
171+
class CustomImportPlugin {
172+
install(lessInstance, pluginManager) {
173+
pluginManager.addFileManager(new ResolvePlugin());
174+
}
175+
}
176+
144177
async function getCodeFromLess(testId, options = {}, context = {}) {
145178
let pathToFile;
146179

@@ -186,40 +219,6 @@ async function getCodeFromLess(testId, options = {}, context = {}) {
186219
...lessOptions,
187220
};
188221

189-
const less = (await import("less")).default;
190-
191-
class ResolvePlugin extends less.FileManager {
192-
supports(filename) {
193-
if (filename[0] === "/" || path.win32.isAbsolute(filename)) {
194-
return true;
195-
}
196-
197-
if (this.isPathAbsolute(filename)) {
198-
return false;
199-
}
200-
201-
return true;
202-
}
203-
204-
supportsSync() {
205-
return false;
206-
}
207-
208-
async loadFile(filename, ...args) {
209-
const result =
210-
pathMap[filename] ||
211-
path.resolve(__dirname, "..", "fixtures", filename);
212-
213-
return super.loadFile(result, ...args);
214-
}
215-
}
216-
217-
class CustomImportPlugin {
218-
install(lessInstance, pluginManager) {
219-
pluginManager.addFileManager(new ResolvePlugin());
220-
}
221-
}
222-
223222
mergedOptions.plugins.unshift(new CustomImportPlugin());
224223

225224
return less.render(data.toString(), mergedOptions);

test/implementation.test.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ import {
99

1010
describe('"implementation" option', () => {
1111
it("should work", async () => {
12-
const less = (await import("less")).default;
1312
const testId = "./basic.less";
1413
const compiler = getCompiler(testId, {
15-
implementation: less,
14+
implementation: require("less"),
1615
});
1716
const stats = await compile(compiler);
1817
const codeFromBundle = getCodeFromBundle(stats, compiler);
@@ -26,9 +25,8 @@ describe('"implementation" option', () => {
2625

2726
it("should work when implementation option is string", async () => {
2827
const testId = "./basic.less";
29-
3028
const compiler = getCompiler(testId, {
31-
implementation: "less",
29+
implementation: require.resolve("less"),
3230
});
3331
const stats = await compile(compiler);
3432
const codeFromBundle = getCodeFromBundle(stats, compiler);

test/loader.test.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import {
1414
validateDependencies,
1515
} from "./helpers";
1616

17+
const CustomFileLoaderPlugin = require("./fixtures/folder/customFileLoaderPlugin");
18+
1719
const nodeModulesPath = path.resolve(__dirname, "fixtures", "node_modules");
1820

1921
jest.setTimeout(30000);
@@ -105,11 +107,6 @@ describe("loader", () => {
105107
});
106108

107109
it("should work third-party plugins as fileLoader", async () => {
108-
const getCustomFileLoaderPlugin = (
109-
await import("./fixtures/folder/customFileLoaderPlugin")
110-
).default.default;
111-
const CustomFileLoaderPlugin = await getCustomFileLoaderPlugin();
112-
113110
const testId = "./file-load.less";
114111
const compiler = getCompiler(testId, {
115112
lessOptions: {
@@ -805,9 +802,7 @@ describe("loader", () => {
805802
let contextInClass = false;
806803
let contextInObject = false;
807804

808-
const less = (await import("less")).default;
809-
810-
class Plugin extends less.FileManager {
805+
class Plugin extends require("less").FileManager {
811806
constructor(less, pluginManager) {
812807
super();
813808

0 commit comments

Comments
 (0)