Closed jls-tschanzc closed 4 years ago
Sounds reasonable. I'll investigate!
Forgot to post my tsconfig, thanks for checking :)
{
"compilerOptions": {
"target": "ES2018",
"module": "commonjs",
"lib": ["ES2018"],
"sourceMap": false,
"outDir": "./dist",
"strict": true,
"noImplicitAny": true,
"baseUrl": "./src",
"typeRoots": ["node_modules/@types"],
"types": ["node"],
"esModuleInterop": true,
"inlineSourceMap": false,
"resolveJsonModule": true,
"forceConsistentCasingInFileNames": true
}
}
Alright so I looked into this and the behavior is not a bug.
The following things appear:
target=node
, which - by default - does not bundle in any modules. So the plugin is not even active.bundle-node-modules
, which activates the plugin - however, you use as rule "aws-sdk": "aws-sdk"
, which - in the string array mode - would translate to "aws-sdk => aws-sdk"
. Obviously, this is not what is desired. Potentially this is a confusion with "react": "React"
. In this case a global variable React
would be used instead of require('react')
.For an existing module you'd still want require("aws-sdk")
. So you now have 2 options.
"aws-sdk => require('aws-sdk')
"dependencies": {
"aws-sdk": "2.585.0"
},
"externals": [
"aws-sdk"
],
"devDependencies": {
"@types/aws-lambda": "^8.10.47",
"@types/node": "^13.9.8",
"parcel-bundler": "^1.12.4",
"parcel-plugin-externals": "^0.3.3-pre.20200323.2",
"typescript": "^3.8.3"
},
"engines": {
"node": ">=12.0.0 <13.0.0"
}
Hope that helps!
Thanks @FlorianRappl for taking the time to check this, but sadly your proposed way does not work. When I set:
"externals": [
"aws-sdk"
],
or
"externals": [
"aws-sdk => require('aws-sdk')"
],
parcel will fail:
> parcel build ./src/index.ts --out-dir dist --out-file index.js --global handler --target=node --experimental-scope-hoisting --no-source-maps --no-content-hash --bundle-node-modules
🚨 /aws-sdk.external:1:23: Cannot resolve dependency 'aws-sdk'
at Resolver.resolve (node_modules/parcel-bundler/src/Resolver.js:71:17)
at async Bundler.resolveAsset (node_modules/parcel-bundler/src/Bundler.js:433:18)
at async Bundler.resolveDep (node_modules/parcel-bundler/src/Bundler.js:484:14)
at async node_modules/parcel-bundler/src/Bundler.js:608:26
at async Promise.all (index 1)
at async Bundler.loadAsset (node_modules/parcel-bundler/src/Bundler.js:599:21)
at async node_modules/parcel-bundler/src/Bundler.js:610:13
at async Promise.all (index 2)
at async Bundler.loadAsset (node_modules/parcel-bundler/src/Bundler.js:599:21)
at async Bundler.processAsset (node_modules/parcel-bundler/src/Bundler.js:557:5)
It works for me - sure you, e.g., installed aws-sdk
?
Keep in mind that the package must exist - externals just means that it will not be bundled in.
After a bit more testing I found the issue to be the --experimental-scope-hoisting
parcel option. When using the build command (e.g.):
parcel build ./src/index.ts --out-dir dist --out-file index.js --global handler --target=node --bundle-node-modules --no-minify --experimental-scope-hoisting
it will fail as I described in my last comment but without using the scope-hoisting:
parcel build ./src/index.ts --out-dir dist --out-file index.js --global handler --target=node --bundle-node-modules --no-minify
it works as you said. Sadly this leads to an increased final bundle size.
Yeah good point. Not sure yet if its something about this configuration or in general.
Note that parcel's scope hoisting option is experimental and that parcel does not make a guarantee on its correctness (as a matter of fact it sometimes misses important stuff).
Env:
Code written in Typescript.
What I wanted to achieve:
Generally bundle all
node_modules
except a few external ones ("aws-sdk" for a lambda in my case).Problem I encountered:
My
index.ts
looks something like this:When I compile this normally with e.g.
parcel build ./src/index.ts --out-dir dist --out-file index.js --global handler --target=node --experimental-scope-hoisting --no-source-maps --no-content-hash
it works correctly and therequire('aws-sdk')
is correctly left in the output.But if I compile it with the
--bundle-node-modules
it breaks and the output contains something like this:also the parcel output shows:
In both cases the
require('util')
is present in the output as it should.