Skip to content

Commit c7f8799

Browse files
authoredJun 17, 2020
fix: respect 'use strict' (#77)
1 parent 9e2cec4 commit c7f8799

9 files changed

+189
-31
lines changed
 

‎README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@ import $ from 'jquery';
486486
}.call(window, document));
487487
```
488488

489+
> ⚠ Do not use this option if source code contains ES module import(s)
490+
489491
### additionalCode
490492

491493
Type: `String`
@@ -507,7 +509,7 @@ module.exports = {
507509
moduleName: 'jquery',
508510
name: '$',
509511
},
510-
additionalCode: 'var someVariable = 1;',
512+
additionalCode: 'var define = false;',
511513
},
512514
},
513515
],
@@ -522,7 +524,7 @@ Generate output:
522524
```js
523525
import $ from 'jquery';
524526

525-
var someVariable = 1;
527+
var define = false;
526528

527529
// ...
528530
// Code

‎package-lock.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
"dependencies": {
4444
"loader-utils": "^2.0.0",
4545
"schema-utils": "^2.7.0",
46-
"source-map": "^0.6.1"
46+
"source-map": "^0.6.1",
47+
"strip-comments": "^2.0.1"
4748
},
4849
"devDependencies": {
4950
"@babel/cli": "^7.10.1",

‎src/index.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import validateOptions from 'schema-utils';
99

1010
import schema from './options.json';
1111

12-
import { getImports, renderImports } from './utils';
12+
import { getImports, renderImports, sourceHasUseStrict } from './utils';
1313

1414
const HEADER = '/*** IMPORTS FROM imports-loader ***/\n';
1515

@@ -37,10 +37,13 @@ export default function loader(content, sourceMap) {
3737
return;
3838
}
3939

40+
// We don't need to remove 'use strict' manually, because `terser` do it
41+
const directive = sourceHasUseStrict(content);
42+
4043
importsCode += Object.entries(imports).reduce(
4144
(accumulator, item) =>
4245
`${accumulator}${renderImports(this, type, item[0], item[1])}\n`,
43-
''
46+
directive ? "'use strict';\n" : ''
4447
);
4548
}
4649

‎src/utils.js

+23-26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
import { stringifyRequest } from 'loader-utils';
2+
import strip from 'strip-comments';
3+
4+
function forError(item) {
5+
return typeof item === 'string'
6+
? item
7+
: `\n${JSON.stringify(item, null, ' ')}\n`;
8+
}
9+
10+
function sourceHasUseStrict(source) {
11+
const str = strip(source).trim();
12+
13+
return str.startsWith("'use strict'") || str.startsWith('"use strict"');
14+
}
215

316
function resolveImports(type, item) {
417
const defaultSyntax = type === 'module' ? 'default' : 'single';
@@ -50,11 +63,7 @@ function resolveImports(type, item) {
5063
throw new Error(
5164
`The "${result.syntax}" syntax does not support "${
5265
result.alias
53-
}" alias in "${
54-
typeof item === 'string'
55-
? item
56-
: `\n${JSON.stringify(item, null, ' ')}\n`
57-
}" value`
66+
}" alias in "${forError(item)}" value`
5867
);
5968
}
6069

@@ -65,11 +74,7 @@ function resolveImports(type, item) {
6574
throw new Error(
6675
`The "${result.syntax}" syntax does not support "${
6776
result.name
68-
}" name in "${
69-
typeof item === 'string'
70-
? item
71-
: `\n${JSON.stringify(item, null, ' ')}\n`
72-
}" value`
77+
}" name in "${forError(item)}" value`
7378
);
7479
}
7580

@@ -78,11 +83,9 @@ function resolveImports(type, item) {
7883
type === 'commonjs'
7984
) {
8085
throw new Error(
81-
`The "${type}" type does not support the "${result.syntax}" syntax in "${
82-
typeof item === 'string'
83-
? item
84-
: `\n${JSON.stringify(item, null, ' ')}\n`
85-
}" value`
86+
`The "${type}" type does not support the "${
87+
result.syntax
88+
}" syntax in "${forError(item)}" value`
8689
);
8790
}
8891

@@ -93,11 +96,7 @@ function resolveImports(type, item) {
9396
throw new Error(
9497
`The "${type}" format does not support the "${
9598
result.syntax
96-
}" syntax in "${
97-
typeof item === 'string'
98-
? item
99-
: `\n${JSON.stringify(item, null, ' ')}\n`
100-
}" value`
99+
}" syntax in "${forError(item)}" value`
101100
);
102101
}
103102

@@ -106,11 +105,9 @@ function resolveImports(type, item) {
106105
typeof result.name === 'undefined'
107106
) {
108107
throw new Error(
109-
`The "${result.syntax}" syntax needs the "name" option in "${
110-
typeof item === 'string'
111-
? item
112-
: `\n${JSON.stringify(item, null, ' ')}\n`
113-
}" value`
108+
`The "${result.syntax}" syntax needs the "name" option in "${forError(
109+
item
110+
)}" value`
114111
);
115112
}
116113

@@ -315,4 +312,4 @@ function renderImports(loaderContext, type, moduleName, imports) {
315312
return code;
316313
}
317314

318-
export { getImports, renderImports };
315+
export { sourceHasUseStrict, getImports, renderImports };

‎test/__snapshots__/loader.test.js.snap

+82
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,88 @@ var someCode = {
649649

650650
exports[`loader should work with "single" imports without syntax: warnings 1`] = `Array []`;
651651

652+
exports[`loader should work with "use-strict" not in program with CommonJS modules: errors 1`] = `Array []`;
653+
654+
exports[`loader should work with "use-strict" not in program with CommonJS modules: module 1`] = `
655+
"/*** IMPORTS FROM imports-loader ***/
656+
var lib_1 = require(\\"lib_1\\");
657+
658+
var myObject = { foo: 'bar' };
659+
660+
function test() {
661+
'use strict';
662+
663+
return 'test';
664+
}
665+
"
666+
`;
667+
668+
exports[`loader should work with "use-strict" not in program with CommonJS modules: warnings 1`] = `Array []`;
669+
670+
exports[`loader should work with "use-strict" not in program with ES modules: errors 1`] = `Array []`;
671+
672+
exports[`loader should work with "use-strict" not in program with ES modules: module 1`] = `
673+
"/*** IMPORTS FROM imports-loader ***/
674+
import lib_1 from \\"lib_1\\";
675+
676+
var myObject = { foo: 'bar' };
677+
678+
function test() {
679+
'use strict';
680+
681+
return 'test';
682+
}
683+
"
684+
`;
685+
686+
exports[`loader should work with "use-strict" not in program with ES modules: warnings 1`] = `Array []`;
687+
688+
exports[`loader should work with "use-strict" with CommonJS modules: errors 1`] = `Array []`;
689+
690+
exports[`loader should work with "use-strict" with CommonJS modules: module 1`] = `
691+
"/*** IMPORTS FROM imports-loader ***/
692+
'use strict';
693+
var lib_1 = require(\\"lib_1\\");
694+
695+
/* Comment */
696+
697+
'use strict';
698+
699+
var myObject = { foo: 'bar' };
700+
701+
function test() {
702+
'use strict';
703+
704+
return 'test';
705+
}
706+
"
707+
`;
708+
709+
exports[`loader should work with "use-strict" with CommonJS modules: warnings 1`] = `Array []`;
710+
711+
exports[`loader should work with "use-strict" with ES modules: errors 1`] = `Array []`;
712+
713+
exports[`loader should work with "use-strict" with ES modules: module 1`] = `
714+
"/*** IMPORTS FROM imports-loader ***/
715+
'use strict';
716+
import lib_1 from \\"lib_1\\";
717+
718+
/* Comment */
719+
720+
'use strict';
721+
722+
var myObject = { foo: 'bar' };
723+
724+
function test() {
725+
'use strict';
726+
727+
return 'test';
728+
}
729+
"
730+
`;
731+
732+
exports[`loader should work with "use-strict" with ES modules: warnings 1`] = `Array []`;
733+
652734
exports[`loader should work with a string syntax using CommonJS: errors 1`] = `Array []`;
653735

654736
exports[`loader should work with a string syntax using CommonJS: module 1`] = `
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
var myObject = { foo: 'bar' };
2+
3+
function test() {
4+
'use strict';
5+
6+
return 'test';
7+
}

‎test/fixtures/use-strict.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* Comment */
2+
3+
'use strict';
4+
5+
var myObject = { foo: 'bar' };
6+
7+
function test() {
8+
'use strict';
9+
10+
return 'test';
11+
}

‎test/loader.test.js

+50
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,56 @@ describe('loader', () => {
149149
expect(getWarnings(stats)).toMatchSnapshot('warnings');
150150
});
151151

152+
it('should work with "use-strict" with ES modules', async () => {
153+
const compiler = getCompiler('use-strict.js', {
154+
imports: 'lib_1',
155+
});
156+
const stats = await compile(compiler);
157+
158+
expect(getModuleSource('./use-strict.js', stats)).toMatchSnapshot('module');
159+
expect(getErrors(stats)).toMatchSnapshot('errors');
160+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
161+
});
162+
163+
it('should work with "use-strict" with CommonJS modules', async () => {
164+
const compiler = getCompiler('use-strict.js', {
165+
type: 'commonjs',
166+
imports: 'lib_1',
167+
});
168+
const stats = await compile(compiler);
169+
170+
expect(getModuleSource('./use-strict.js', stats)).toMatchSnapshot('module');
171+
expect(getErrors(stats)).toMatchSnapshot('errors');
172+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
173+
});
174+
175+
it('should work with "use-strict" not in program with ES modules', async () => {
176+
const compiler = getCompiler('use-strict-in-function.js', {
177+
imports: 'lib_1',
178+
});
179+
const stats = await compile(compiler);
180+
181+
expect(
182+
getModuleSource('./use-strict-in-function.js', stats)
183+
).toMatchSnapshot('module');
184+
expect(getErrors(stats)).toMatchSnapshot('errors');
185+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
186+
});
187+
188+
it('should work with "use-strict" not in program with CommonJS modules', async () => {
189+
const compiler = getCompiler('use-strict-in-function.js', {
190+
type: 'commonjs',
191+
imports: 'lib_1',
192+
});
193+
const stats = await compile(compiler);
194+
195+
expect(
196+
getModuleSource('./use-strict-in-function.js', stats)
197+
).toMatchSnapshot('module');
198+
expect(getErrors(stats)).toMatchSnapshot('errors');
199+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
200+
});
201+
152202
it('should work with "imports", "wrapper" and "additionalCode" options', async () => {
153203
const compiler = getCompiler('some-library.js', {
154204
imports: {

0 commit comments

Comments
 (0)
Please sign in to comment.