Skip to content

Commit 0339f93

Browse files
authored
fix(commonjs)!: dynamic require root check was broken in some cases (#1461)
* fix(commonjs): dynamic require root check was broken in some cases * fix(commonjs): fixed a commonjs unit test based on OS paths * test(commonjs): attempt 2 at having tests not fail in CI Using the normalized path in _all_ the properties of the error * test: 1st try at the test * test(commonjs): the dynamic root must ignore conflicting backslashes * test(commonjs): added a test specifically for Windows
1 parent 5d477ec commit 0339f93

File tree

3 files changed

+76
-11
lines changed

3 files changed

+76
-11
lines changed

packages/commonjs/src/index.js

+9-7
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export default function commonjs(options = {}) {
112112
let requireResolver;
113113

114114
function transformAndCheckExports(code, id) {
115+
const normalizedId = normalizePathSlashes(id);
115116
const { isEsModule, hasDefaultExport, hasNamedExports, ast } = analyzeTopLevelStatements(
116117
this.parse,
117118
code,
@@ -127,7 +128,7 @@ export default function commonjs(options = {}) {
127128
}
128129

129130
if (
130-
!dynamicRequireModules.has(normalizePathSlashes(id)) &&
131+
!dynamicRequireModules.has(normalizedId) &&
131132
(!(hasCjsKeywords(code, ignoreGlobal) || requireResolver.isRequiredId(id)) ||
132133
(isEsModule && !options.transformMixedEsModules))
133134
) {
@@ -136,18 +137,19 @@ export default function commonjs(options = {}) {
136137
}
137138

138139
const needsRequireWrapper =
139-
!isEsModule &&
140-
(dynamicRequireModules.has(normalizePathSlashes(id)) || strictRequiresFilter(id));
140+
!isEsModule && (dynamicRequireModules.has(normalizedId) || strictRequiresFilter(id));
141141

142142
const checkDynamicRequire = (position) => {
143-
if (id.indexOf(dynamicRequireRoot) !== 0) {
143+
const normalizedRequireRoot = normalizePathSlashes(dynamicRequireRoot);
144+
145+
if (normalizedId.indexOf(normalizedRequireRoot) !== 0) {
144146
this.error(
145147
{
146148
code: 'DYNAMIC_REQUIRE_OUTSIDE_ROOT',
147-
id,
149+
normalizedId,
148150
dynamicRequireRoot,
149-
message: `"${id}" contains dynamic require statements but it is not within the current dynamicRequireRoot "${dynamicRequireRoot}". You should set dynamicRequireRoot to "${dirname(
150-
id
151+
message: `"${normalizedId}" contains dynamic require statements but it is not within the current dynamicRequireRoot "${normalizedRequireRoot}". You should set dynamicRequireRoot to "${dirname(
152+
normalizedId
151153
)}" or one of its parent directories.`
152154
},
153155
position

packages/commonjs/test/helpers/util.js

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ function commonjs(options) {
77
return commonjsPlugin(options);
88
}
99

10+
function normalizePathSlashes(path) {
11+
return path.replace(/\\/g, '/');
12+
}
13+
1014
function requireWithContext(code, context) {
1115
const module = { exports: {} };
1216
const contextWithExports = { ...context, module, exports: module.exports };
@@ -90,5 +94,6 @@ module.exports = {
9094
executeBundle,
9195
getCodeFromBundle,
9296
getCodeMapFromBundle,
97+
normalizePathSlashes,
9398
runCodeSplitTest
9499
};

packages/commonjs/test/test.js

+62-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ const { testBundle } = require('../../../util/test');
1313

1414
const { peerDependencies } = require('../package.json');
1515

16-
const { commonjs, executeBundle, getCodeFromBundle } = require('./helpers/util.js');
16+
const {
17+
commonjs,
18+
executeBundle,
19+
getCodeFromBundle,
20+
normalizePathSlashes
21+
} = require('./helpers/util.js');
1722

1823
install();
1924
test.beforeEach(() => process.chdir(__dirname));
@@ -715,9 +720,16 @@ test('throws when there is a dynamic require from outside dynamicRequireRoot', a
715720
}
716721

717722
const cwd = process.cwd();
718-
const id = path.join(cwd, 'fixtures/samples/dynamic-require-outside-root/main.js');
719-
const dynamicRequireRoot = path.join(cwd, 'fixtures/samples/dynamic-require-outside-root/nested');
720-
const minimalDynamicRequireRoot = path.join(cwd, 'fixtures/samples/dynamic-require-outside-root');
723+
const id = normalizePathSlashes(
724+
path.join(cwd, 'fixtures/samples/dynamic-require-outside-root/main.js')
725+
);
726+
const dynamicRequireRoot = normalizePathSlashes(
727+
path.join(cwd, 'fixtures/samples/dynamic-require-outside-root/nested')
728+
);
729+
const minimalDynamicRequireRoot = normalizePathSlashes(
730+
path.join(cwd, 'fixtures/samples/dynamic-require-outside-root')
731+
);
732+
721733
t.like(error, {
722734
message: `"${id}" contains dynamic require statements but it is not within the current dynamicRequireRoot "${dynamicRequireRoot}". You should set dynamicRequireRoot to "${minimalDynamicRequireRoot}" or one of its parent directories.`,
723735
pluginCode: 'DYNAMIC_REQUIRE_OUTSIDE_ROOT',
@@ -726,6 +738,52 @@ test('throws when there is a dynamic require from outside dynamicRequireRoot', a
726738
});
727739
});
728740

741+
test('does not throw when a dynamic require uses different slashes than dynamicRequireRoot', async (t) => {
742+
let error = null;
743+
try {
744+
await rollup({
745+
input: 'fixtures/samples/dynamic-require-outside-root/main.js',
746+
plugins: [
747+
commonjs({
748+
dynamicRequireRoot: 'fixtures\\samples\\dynamic-require-outside-root',
749+
dynamicRequireTargets: [
750+
'fixtures\\samples\\dynamic-require-outside-root\\nested\\target.js'
751+
]
752+
})
753+
]
754+
});
755+
} catch (err) {
756+
error = err;
757+
}
758+
759+
t.is(error, null);
760+
});
761+
762+
// On Windows, avoid a false error about a module not being in the dynamic require root due to
763+
// incoherent slashes/backslashes in the paths.
764+
if (os.platform() === 'win32') {
765+
test('correctly asserts dynamicRequireRoot on Windows', async (t) => {
766+
let error = null;
767+
try {
768+
await rollup({
769+
input: 'fixtures/samples/dynamic-require-outside-root/main.js',
770+
plugins: [
771+
commonjs({
772+
dynamicRequireRoot: 'fixtures/samples/dynamic-require-outside-root',
773+
dynamicRequireTargets: [
774+
'fixtures/samples/dynamic-require-outside-root/nested/target.js'
775+
]
776+
})
777+
]
778+
});
779+
} catch (err) {
780+
error = err;
781+
}
782+
783+
t.is(error, null);
784+
});
785+
}
786+
729787
test('does not transform typeof exports for mixed modules', async (t) => {
730788
const bundle = await rollup({
731789
input: 'fixtures/samples/mixed-module-typeof-exports/main.js',

0 commit comments

Comments
 (0)