Skip to content

Commit f35c64c

Browse files
committed
feat(build/serve): Support multiple node_module paths, closes #75
1 parent 5d7dc39 commit f35c64c

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

__tests__/webpackConfig.spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const mockApi = {
2121
} else if (path.match('./node_modules/mockExternal/index.js')) {
2222
return 'mockExternalIndex'
2323
}
24+
return path
2425
})
2526
}
2627

@@ -115,6 +116,10 @@ describe('chainWebpack', () => {
115116
describe.each(['production', 'development'])('getExternals in %s', env => {
116117
process.env.NODE_ENV = env
117118

119+
fs.existsSync.mockImplementation(
120+
path => path === 'mockExternalPath' || path === 'customExternalPath'
121+
)
122+
118123
const mockGetExternals = async (
119124
modulePkg = {},
120125
pluginOptions,
@@ -198,4 +203,16 @@ describe.each(['production', 'development'])('getExternals in %s', env => {
198203
// Not read from default path
199204
expect(fs.readFileSync).not.toBeCalledWith(`mockExternalPath`)
200205
})
206+
207+
test('Checks multiple locations for dep package.json', async () => {
208+
await mockGetExternals(
209+
{},
210+
{ nodeModulesPath: ['wrongPath', 'customNodeModulesPath'] }
211+
)
212+
// Checked both paths
213+
expect(fs.existsSync).toBeCalledWith('wrongPath/mockExternal/package.json')
214+
expect(fs.existsSync).toBeCalledWith('customExternalPath')
215+
// Read from proper path
216+
expect(fs.readFileSync).toBeCalledWith('customExternalPath')
217+
})
201218
})

lib/webpackConfig.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ async function chainWebpack (api, pluginOptions, config) {
4141
// Find all the dependencies without a `main` property or with a `binary` property or set by user and add them as webpack externals
4242
function getExternals (api, pluginOptions) {
4343
const nodeModulesPath = pluginOptions.nodeModulesPath || './node_modules'
44+
let nodeModulesPaths = []
45+
if (Array.isArray(nodeModulesPath)) {
46+
// Set to user-defined array
47+
nodeModulesPaths = nodeModulesPath
48+
} else {
49+
// Add path to list
50+
nodeModulesPaths.push(nodeModulesPath)
51+
}
4452
const userExternals = pluginOptions.externals || []
4553
const userExternalsWhitelist = []
4654
userExternals.forEach((d, i) => {
@@ -53,9 +61,20 @@ function getExternals (api, pluginOptions) {
5361
const externalsList = Object.keys(dependencies || {}).filter(dep => {
5462
// Return true if we want to add a dependency to externals
5563
try {
56-
const pgkString = fs
57-
.readFileSync(api.resolve(`${nodeModulesPath}/${dep}/package.json`))
58-
.toString()
64+
let pgkString
65+
for (const path of nodeModulesPaths) {
66+
// Check if package.json exists
67+
if (fs.existsSync(api.resolve(`${path}/${dep}/package.json`))) {
68+
// If it does, read it and break
69+
pgkString = fs
70+
.readFileSync(api.resolve(`${path}/${dep}/package.json`))
71+
.toString()
72+
break
73+
}
74+
}
75+
if (!pgkString) {
76+
throw new Error(`Could not find a package.json for module ${dep}`)
77+
}
5978
const pkg = JSON.parse(pgkString)
6079
const fields = ['main', 'module', 'jsnext:main', 'browser']
6180
return (

0 commit comments

Comments
 (0)