Skip to content

Commit 7265bc8

Browse files
authoredJun 16, 2020
refactor: options for commonjs
1 parent bef708f commit 7265bc8

File tree

6 files changed

+134
-54
lines changed

6 files changed

+134
-54
lines changed
 

‎README.md

+23-12
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ require(`imports-loader?imports[]=default%20jquery%20$&imports[]=angular!./examp
7575
```
7676

7777
```js
78-
require(`imports-loader?type=commonjsimports[]=default%20jquery%20$&imports[]=angular!./example.js`);
78+
require(`imports-loader?type=commonjsimports[]=single%20jquery%20$&imports[]=angular!./example.js`);
7979
// Adds the following code to the beginning of example.js:
8080
//
8181
// var $ = require("jquery");
@@ -114,14 +114,13 @@ module.exports = {
114114
options: {
115115
type: 'commonjs',
116116
imports: [
117-
'default ./lib_1 $',
118-
'default ./lib_2 lib_2_default',
119-
'named ./lib_2 lib2_method_1',
120-
'named ./lib_2 lib2_method_2 lib_2_method_2_short',
121-
'default ./lib_3 lib_3_defaul',
122-
'namespace ./lib_3 lib_3_all',
123-
'side-effect ./lib_4',
124-
'default jquery $',
117+
'single ./lib_1 $',
118+
'single ./lib_2 lib_2_default',
119+
'multiple ./lib_2 lib2_method_1',
120+
'multiple ./lib_2 lib2_method_2 lib_2_method_2_short',
121+
'single ./lib_3 lib_3_defaul',
122+
'pure ./lib_4',
123+
'single jquery $',
125124
{
126125
moduleName: 'angular',
127126
name: 'angular',
@@ -223,13 +222,19 @@ String values let you specify import syntax, moduleName, name, and alias.
223222

224223
String syntax - `[[syntax] [moduleName] [name] [alias]]`, where:
225224

226-
- `[syntax]` - can be `default`, `named`, `namespace` or `side-effect`
225+
- `[syntax]`:
226+
227+
- if type `module`- can be `default`, `named`, `namespace` or `side-effect`
228+
- if type `commonjs`- can be `single`, `multiple` or `pure`
229+
227230
- `[moduleName]` - name of an imported module (**required**)
228231
- `[name]` - name of an imported value (**required**)
229232
- `[alias]` - alias of an imported value (**may be omitted**)
230233

231234
Examples:
232235

236+
If type `module`:
237+
233238
- `[Foo]` - generates `import Foo from "Foo";`.
234239
- `[default Foo]` - generates `import Foo from "Foo";`.
235240
- `[default ./my-lib Foo]` - generates `import Foo from "./my-lib";`.
@@ -240,6 +245,14 @@ Examples:
240245
- `[[default Foo] [namespace Foo FooA]]` - generates `import Foo, * as FooA from "Foo";`.
241246
- `[side-effect Foo]` - generates `import "Foo";`.
242247

248+
If type `commonjs`:
249+
250+
- `[Foo]` - generates `const Foo = require("Foo");`.
251+
- `[single Foo]` - generates `const Foo = require("Foo");`.
252+
- `[single ./my-lib Foo]` - generates `const Foo = require("./my-lib");`.
253+
- `[multiple Foo FooA Bar]` - generates `const { FooA:Bar } = require("Foo");`.
254+
- `[pure Foo]` - generates `require("Foo");`.
255+
243256
> ⚠ Aliases can't be used together with `default` or `side-effect` syntax.
244257
245258
###### Examples
@@ -296,7 +309,6 @@ module.exports = {
296309
{
297310
loader: 'imports-loader',
298311
options: {
299-
type: 'commonjs',
300312
imports: {
301313
syntax: 'named',
302314
moduleName: './lib_2',
@@ -334,7 +346,6 @@ module.exports = {
334346
{
335347
loader: 'imports-loader',
336348
options: {
337-
type: 'commonjs',
338349
imports: [
339350
{
340351
moduleName: 'angular',

‎src/options.json

+9-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@
55
"additionalProperties": false,
66
"properties": {
77
"syntax": {
8-
"enum": ["default", "named", "namespace", "side-effect"]
8+
"enum": [
9+
"default",
10+
"named",
11+
"namespace",
12+
"side-effect",
13+
"single",
14+
"multiple",
15+
"pure"
16+
]
917
},
1018
"moduleName": {
1119
"type": "string",

‎src/utils.js

+75-29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { stringifyRequest } from 'loader-utils';
22

33
function resolveImports(type, item) {
4+
const defaultSyntax = type === 'module' ? 'default' : 'single';
45
let result;
56

67
if (typeof item === 'string') {
@@ -13,7 +14,7 @@ function resolveImports(type, item) {
1314
if (splittedItem.length === 1) {
1415
result = {
1516
type,
16-
syntax: 'default',
17+
syntax: defaultSyntax,
1718
moduleName: splittedItem[0],
1819
name: splittedItem[0],
1920
// eslint-disable-next-line no-undefined
@@ -29,9 +30,9 @@ function resolveImports(type, item) {
2930
};
3031
}
3132
} else {
32-
result = { syntax: 'default', ...item };
33+
result = { syntax: defaultSyntax, ...item };
3334

34-
if (result.syntax === 'default' && !result.name) {
35+
if (result.syntax === defaultSyntax && !result.name) {
3536
result.name = result.moduleName;
3637
}
3738
}
@@ -43,7 +44,7 @@ function resolveImports(type, item) {
4344
}
4445

4546
if (
46-
['default', 'side-effect'].includes(result.syntax) &&
47+
['default', 'single', 'side-effect', 'pure'].includes(result.syntax) &&
4748
typeof result.alias !== 'undefined'
4849
) {
4950
throw new Error(
@@ -52,22 +53,34 @@ function resolveImports(type, item) {
5253
}
5354

5455
if (
55-
['side-effect'].includes(result.syntax) &&
56+
['side-effect', 'pure'].includes(result.syntax) &&
5657
typeof result.name !== 'undefined'
5758
) {
5859
throw new Error(
5960
`The "${result.syntax}" syntax can't have "${result.name}" name in "${item}" value`
6061
);
6162
}
6263

63-
if (['namespace'].includes(result.syntax) && type === 'commonjs') {
64+
if (
65+
['default', 'namespace', 'named', 'side-effect'].includes(result.syntax) &&
66+
type === 'commonjs'
67+
) {
6468
throw new Error(
65-
`The "commonjs" type not support "namespace" syntax import in "${item}" value`
69+
`The "commonjs" type not support "${result.syntax}" syntax import in "${item}" value`
6670
);
6771
}
6872

6973
if (
70-
['namespace', 'named'].includes(result.syntax) &&
74+
['single', 'multiple', 'pure'].includes(result.syntax) &&
75+
type === 'module'
76+
) {
77+
throw new Error(
78+
`The "module" type not support "${result.syntax}" syntax import in "${item}" value`
79+
);
80+
}
81+
82+
if (
83+
['namespace', 'named', 'multiple'].includes(result.syntax) &&
7184
typeof result.name === 'undefined'
7285
) {
7386
throw new Error(
@@ -97,18 +110,23 @@ function getImports(type, imports) {
97110
sortedResults[item.moduleName].push(item);
98111
}
99112

113+
const defaultSyntax = type === 'module' ? 'default' : 'single';
114+
100115
for (const item of Object.entries(sortedResults)) {
101116
const defaultImports = item[1].filter(
102-
(entry) => entry.syntax === 'default'
117+
(entry) => entry.syntax === defaultSyntax
103118
);
119+
104120
const namespaceImports = item[1].filter(
105121
(entry) => entry.syntax === 'namespace'
106122
);
107123
const sideEffectImports = item[1].filter(
108124
(entry) => entry.syntax === 'side-effect'
109125
);
110126

111-
[defaultImports, namespaceImports, sideEffectImports].forEach(
127+
const pure = item[1].filter((entry) => entry.syntax === 'pure');
128+
129+
[defaultImports, namespaceImports, sideEffectImports, pure].forEach(
112130
(importsSyntax) => {
113131
if (importsSyntax.length > 1) {
114132
const [{ syntax }] = importsSyntax;
@@ -127,37 +145,48 @@ function getImports(type, imports) {
127145
function renderImports(loaderContext, type, imports) {
128146
const [{ moduleName }] = imports;
129147
const defaultImports = imports.filter((item) => item.syntax === 'default');
148+
const singleImports = imports.filter((item) => item.syntax === 'single');
130149
const namedImports = imports.filter((item) => item.syntax === 'named');
150+
const multipleImports = imports.filter((item) => item.syntax === 'multiple');
131151
const namespaceImports = imports.filter(
132152
(item) => item.syntax === 'namespace'
133153
);
134154
const sideEffectImports = imports.filter(
135155
(item) => item.syntax === 'side-effect'
136156
);
157+
const pure = imports.filter((item) => item.syntax === 'pure');
137158
const isModule = type === 'module';
138159

139-
// 1. Import-side-effect
160+
// 1. Module import-side-effect
140161
if (sideEffectImports.length > 0) {
141-
return isModule
142-
? `import ${stringifyRequest(loaderContext, moduleName)};`
143-
: `require(${stringifyRequest(loaderContext, moduleName)});`;
162+
return `import ${stringifyRequest(loaderContext, moduleName)};`;
163+
}
164+
165+
// 2. CommonJs pure
166+
if (pure.length > 0) {
167+
return `require(${stringifyRequest(loaderContext, moduleName)});`;
144168
}
145169

146170
let code = isModule ? 'import' : '';
147171

148-
// 2. Default import
172+
// 3. Module default import
149173
if (defaultImports.length > 0) {
150174
const [{ name }] = defaultImports;
151175

152-
code += isModule
153-
? ` ${name}`
154-
: `var ${name} = require(${stringifyRequest(
155-
loaderContext,
156-
moduleName
157-
)});`;
176+
code += ` ${name}`;
158177
}
159178

160-
// 3. Namespace import
179+
// 4. CommonJs single import
180+
if (singleImports.length > 0) {
181+
const [{ name }] = singleImports;
182+
183+
code += `var ${name} = require(${stringifyRequest(
184+
loaderContext,
185+
moduleName
186+
)});`;
187+
}
188+
189+
// 5. Module namespace import
161190
if (namespaceImports.length > 0) {
162191
if (defaultImports.length > 0) {
163192
code += `,`;
@@ -168,25 +197,42 @@ function renderImports(loaderContext, type, imports) {
168197
code += ` * as ${name}`;
169198
}
170199

171-
// 4. Named import
200+
// 6. Module named import
172201
if (namedImports.length > 0) {
173202
if (defaultImports.length > 0) {
174-
code += isModule ? ', { ' : '\nvar { ';
203+
code += ', { ';
175204
} else {
176-
code += isModule ? ' { ' : 'var { ';
205+
code += ' { ';
177206
}
178207

179208
namedImports.forEach((namedImport, i) => {
180209
const comma = i > 0 ? ', ' : '';
181210
const { name, alias } = namedImport;
182-
const sep = isModule ? ' as ' : ': ';
211+
const sep = ' as ';
212+
213+
code += alias ? `${comma}${name}${sep}${alias}` : `${comma}${name}`;
214+
});
215+
216+
code += ' }';
217+
}
218+
219+
// 7. CommonJs multiple import
220+
if (multipleImports.length > 0) {
221+
if (singleImports.length > 0) {
222+
code += '\nvar { ';
223+
} else {
224+
code += 'var { ';
225+
}
226+
227+
multipleImports.forEach((multipleImport, i) => {
228+
const comma = i > 0 ? ', ' : '';
229+
const { name, alias } = multipleImport;
230+
const sep = ': ';
183231

184232
code += alias ? `${comma}${name}${sep}${alias}` : `${comma}${name}`;
185233
});
186234

187-
code += isModule
188-
? ' }'
189-
: ` } = require(${stringifyRequest(loaderContext, moduleName)});`;
235+
code += ` } = require(${stringifyRequest(loaderContext, moduleName)});`;
190236
}
191237

192238
if (!isModule) {

‎test/fixtures/inline2.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
require('../../src/cjs.js?type=commonjs&imports[]=default%20lib_2%20lib_2_all&imports[]=named%20lib_2%20lib_2_method%20lib_2_method_alias!./some-library.js');
1+
require('../../src/cjs.js?type=commonjs&imports[]=single%20lib_2%20lib_2_all&imports[]=multiple%20lib_2%20lib_2_method%20lib_2_method_alias!./some-library.js');

‎test/loader.test.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ describe('loader', () => {
239239
imports: {
240240
moduleName: './lib_1',
241241
name: '$',
242-
syntax: 'default',
242+
syntax: 'single',
243243
},
244244
});
245245
const stats = await compile(compiler);
@@ -256,12 +256,12 @@ describe('loader', () => {
256256
type: 'commonjs',
257257
imports: [
258258
{
259-
syntax: 'named',
259+
syntax: 'multiple',
260260
moduleName: './lib_2',
261261
name: 'lib2_method_1',
262262
},
263263
{
264-
syntax: 'named',
264+
syntax: 'multiple',
265265
moduleName: './lib_2',
266266
name: 'lib2_method_2',
267267
alias: 'lib_2_method_2_short',
@@ -290,12 +290,12 @@ describe('loader', () => {
290290
name: 'lib_2_all',
291291
},
292292
{
293-
syntax: 'named',
293+
syntax: 'multiple',
294294
moduleName: './lib_2',
295295
name: 'lib2_method_1',
296296
},
297297
{
298-
syntax: 'named',
298+
syntax: 'multiple',
299299
moduleName: './lib_2',
300300
name: 'lib2_method_2',
301301
alias: 'lib_2_method_2_short',
@@ -315,7 +315,7 @@ describe('loader', () => {
315315
const compiler = getCompiler('some-library.js', {
316316
type: 'commonjs',
317317
imports: {
318-
syntax: 'side-effect',
318+
syntax: 'pure',
319319
moduleName: './lib_1',
320320
},
321321
});
@@ -332,11 +332,11 @@ describe('loader', () => {
332332
const compiler = getCompiler('some-library.js', {
333333
type: 'commonjs',
334334
imports: [
335-
'default ./lib_1 $',
336-
'default ./lib_2 lib_2_all',
337-
'named ./lib_2 lib2_method_1',
338-
'named ./lib_2 lib2_method_2 lib_2_method_2_short',
339-
'side-effect ./lib_3',
335+
'single ./lib_1 $',
336+
'single ./lib_2 lib_2_all',
337+
'multiple ./lib_2 lib2_method_1',
338+
'multiple ./lib_2 lib2_method_2 lib_2_method_2_short',
339+
'pure ./lib_3',
340340
],
341341
});
342342
const stats = await compile(compiler);

‎test/validate-options.test.js

+15
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ describe('validate options', () => {
1616
moduleName: 'jQuery',
1717
name: '$',
1818
},
19+
{
20+
syntax: 'namespace',
21+
moduleName: 'jQuery',
22+
name: '$',
23+
},
24+
{
25+
syntax: 'side-effect',
26+
moduleName: 'jQuery',
27+
},
28+
{
29+
syntax: 'multiple',
30+
moduleName: 'jQuery',
31+
name: 'lib',
32+
alias: 'lib_alias',
33+
},
1934
{
2035
syntax: 'named',
2136
moduleName: 'jQuery',

0 commit comments

Comments
 (0)
Please sign in to comment.