Skip to content

Commit d3022b8

Browse files
committed
feat: make any file type importable
This change enables the user to import any file if the loader pipeline is configured in such a way that non-less files are translated. The loader pipeline for non-less files is typically configured with the `issuer` condition matching the .less file extension.
1 parent 7582e5e commit d3022b8

File tree

6 files changed

+61
-12
lines changed

6 files changed

+61
-12
lines changed

src/createWebpackLessPlugin.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ const less = require('less');
22
const loaderUtils = require('loader-utils');
33
const pify = require('pify');
44

5+
const stringifyLoader = require.resolve('./stringifyLoader.js');
56
const trailingSlash = /[\\/]$/;
7+
const isLessCompatible = /\.(le|c)ss$/;
68

79
/**
810
* Creates a Less plugin that uses webpack's resolving engine that is provided by the loaderContext.
@@ -12,8 +14,10 @@ const trailingSlash = /[\\/]$/;
1214
* @returns {LessPlugin}
1315
*/
1416
function createWebpackLessPlugin(loaderContext) {
17+
const { fs } = loaderContext;
1518
const resolve = pify(loaderContext.resolve.bind(loaderContext));
1619
const loadModule = pify(loaderContext.loadModule.bind(loaderContext));
20+
const readFile = pify(fs.readFile.bind(fs));
1721

1822
class WebpackFileManager extends less.FileManager {
1923
supports(/* filename, currentDirectory, options, environment */) { // eslint-disable-line class-methods-use-this
@@ -32,11 +36,17 @@ function createWebpackLessPlugin(loaderContext) {
3236
resolvedFilename = f;
3337
loaderContext.addDependency(resolvedFilename);
3438

35-
return loadModule(`-!${__dirname}/stringify.loader.js!${resolvedFilename}`);
39+
if (isLessCompatible.test(resolvedFilename)) {
40+
return readFile(resolvedFilename)
41+
.then(contents => contents.toString('utf8'));
42+
}
43+
44+
return loadModule([stringifyLoader, resolvedFilename].join('!'))
45+
.then(JSON.parse);
3646
})
3747
.then((contents) => {
3848
return {
39-
contents: JSON.parse(contents),
49+
contents,
4050
filename: resolvedFilename,
4151
};
4252
});

src/stringify.loader.js

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

src/stringifyLoader.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* The stringifyLoader turns any content into a valid JavaScript string. This allows us to load any content
3+
* with loaderContext.loadModule() without webpack complaining about non-JS modules.
4+
*
5+
* @param {string} content
6+
* @return {string}
7+
*/
8+
function stringifyLoader(content) {
9+
return JSON.stringify(content);
10+
}
11+
12+
module.exports = stringifyLoader;

test/helpers/createSpec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const cssFixtures = path.resolve(__dirname, '..', 'fixtures', 'css');
1111
const matchWebpackImports = /(@import\s+(\([^)]+\))?\s*["'])~/g;
1212
const lessBin = require.resolve('.bin/lessc');
1313
const ignore = [
14+
'non-less-import',
1415
'error',
1516
];
1617
/**

test/helpers/moduleRules.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const lessLoader = require.resolve('../../src');
22
const helperLoader = require.resolve('./helperLoader.js');
3+
const someFileLoader = require.resolve('./someFileLoader.js');
34

45
function basic(lessLoaderOptions, lessLoaderContext = {}, inspectCallback = () => {}) {
56
return [{
@@ -20,4 +21,26 @@ function basic(lessLoaderOptions, lessLoaderContext = {}, inspectCallback = () =
2021
}];
2122
}
2223

24+
function nonLessImport(inspectCallback) {
25+
return [{
26+
test: /\.less$/,
27+
loaders: [{
28+
loader: helperLoader,
29+
}, {
30+
loader: 'inspect-loader',
31+
options: {
32+
callback: inspectCallback,
33+
},
34+
}, {
35+
loader: lessLoader,
36+
}],
37+
}, {
38+
test: /some\.file$/,
39+
loaders: [{
40+
loader: someFileLoader,
41+
}],
42+
}];
43+
}
44+
2345
exports.basic = basic;
46+
exports.nonLessImport = nonLessImport;

test/index.test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ test('should not try to resolve import urls', async () => {
3232
await compileAndCompare('imports-url');
3333
});
3434

35+
test('should allow non-less-import', async () => {
36+
let inspect;
37+
const rules = moduleRules.nonLessImport((i) => {
38+
inspect = i;
39+
});
40+
41+
await compile('non-less-import', rules);
42+
43+
const [css] = inspect.arguments;
44+
45+
expect(css).toMatch(/\.some-file {\s*background: hotpink;\s*}\s*/);
46+
});
47+
3548
test('should compile data-uri function', async () => {
3649
await compileAndCompare('data-uri');
3750
});

0 commit comments

Comments
 (0)