Skip to content

Commit ba74ec5

Browse files
committed
fix(externals): user externals with subpaths
1 parent b9cb633 commit ba74ec5

File tree

2 files changed

+58
-35
lines changed

2 files changed

+58
-35
lines changed

__tests__/webpackConfig.spec.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,19 @@ describe.each(['production', 'development'])('getExternals in %s', env => {
183183
hasExternal(externals)
184184
})
185185

186+
test('Dep should be found if external includes a child path', async () => {
187+
const { externals } = await mockGetExternals(
188+
// Prevent it from getting marked as an external by default
189+
{ main: 'It will not be an external by default', name: 'mockExternal' },
190+
// Add it to external list
191+
{ externals: ['mockExternal/lib'] }
192+
)
193+
// External is properly added
194+
expect(externals).toEqual({
195+
'mockExternal/lib': 'require("mockExternal/lib")'
196+
})
197+
})
198+
186199
test('If dep is listed in user list and prefixed with "!" it should not be an external', async () => {
187200
const { externals } = await mockGetExternals(
188201
// Make sure it would have been marked as an external by default

lib/webpackConfig.js

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -69,48 +69,58 @@ function getExternals (api, pluginOptions) {
6969
const userExternals = pluginOptions.externals || []
7070
const userExternalsWhitelist = []
7171
userExternals.forEach((d, i) => {
72-
if (d.match(/^!.*$/)) {
72+
if (d.match(/^!/)) {
7373
userExternals.splice(i, 1)
7474
userExternalsWhitelist.push(d.replace(/^!/, ''))
7575
}
7676
})
7777
const { dependencies } = require(api.resolve('./package.json'))
78-
const externalsList = Object.keys(dependencies || {}).filter(dep => {
79-
// Return true if we want to add a dependency to externals
80-
try {
81-
let pgkString
82-
for (const path of nodeModulesPaths) {
83-
// Check if package.json exists
84-
if (fs.existsSync(api.resolve(`${path}/${dep}/package.json`))) {
85-
// If it does, read it and break
86-
pgkString = fs
87-
.readFileSync(api.resolve(`${path}/${dep}/package.json`))
88-
.toString()
89-
break
78+
const externalsList = Object.keys(dependencies || {}).reduce(
79+
(depList, dep) => {
80+
// Return true if we want to add a dependency to externals
81+
try {
82+
let pgkString
83+
for (const path of nodeModulesPaths) {
84+
// Check if package.json exists
85+
if (fs.existsSync(api.resolve(`${path}/${dep}/package.json`))) {
86+
// If it does, read it and break
87+
pgkString = fs
88+
.readFileSync(api.resolve(`${path}/${dep}/package.json`))
89+
.toString()
90+
break
91+
}
9092
}
93+
if (!pgkString) {
94+
throw new Error(`Could not find a package.json for module ${dep}`)
95+
}
96+
const pkg = JSON.parse(pgkString)
97+
const name = userExternals.find(name =>
98+
new RegExp(`^${pkg.name}`).test(name)
99+
)
100+
const fields = ['main', 'module', 'jsnext:main', 'browser']
101+
if (
102+
// Not whitelisted
103+
userExternalsWhitelist.indexOf(dep) === -1 &&
104+
// Doesn't have main property
105+
(!fields.some(field => field in pkg) ||
106+
// Has binary property
107+
!!pkg.binary ||
108+
// Has gypfile property
109+
!!pkg.gypfile ||
110+
// Listed in user-defined externals list
111+
!!name)
112+
) {
113+
// Use user-provided name if it exists, for subpaths
114+
depList.push(name || dep)
115+
}
116+
} catch (e) {
117+
console.log(e)
118+
depList.push(dep)
91119
}
92-
if (!pgkString) {
93-
throw new Error(`Could not find a package.json for module ${dep}`)
94-
}
95-
const pkg = JSON.parse(pgkString)
96-
const fields = ['main', 'module', 'jsnext:main', 'browser']
97-
return (
98-
// Not whitelisted
99-
userExternalsWhitelist.indexOf(dep) === -1 &&
100-
// Doesn't have main property
101-
(!fields.some(field => field in pkg) ||
102-
// Has binary property
103-
!!pkg.binary ||
104-
// Has gypfile property
105-
!!pkg.gypfile ||
106-
// Listed in user-defined externals list
107-
userExternals.indexOf(pkg.name) > -1)
108-
)
109-
} catch (e) {
110-
console.log(e)
111-
return true
112-
}
113-
})
120+
return depList
121+
},
122+
[]
123+
)
114124
let externals = {}
115125
externalsList.forEach(d => {
116126
// Set external to be required during runtime

0 commit comments

Comments
 (0)