New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Import single value (for security reasons) #2310
Comments
in my built code there a like that reads:
This is the entire contents of the config.js file, only |
You could use an envfile |
@mischnic do you have any suggestions? |
You could create a
and then use it like this: (Inspired by #2299) |
I ran into a similar problem trying to import just the
|
Not sure how easy this is to do. You basically want to do tree shaking for json assets. |
My use case feels similar to this issue (tree shaking for JS assets) but not quite since my example is importing a JSON asset. Should I track JSON asset tree-shaking in a separate ticket (don't see anything open for this at the moment)? |
@macklinu JSON files get transformed to JS and JS gets transformed by babel and gathers information for treeshaking so in theory it should already do this. Feel free to experiment with it using |
In practice: (with treeshaking) (function() {
var a = {};
a = {
version: "1.2.3",
scripts: {
build: "parcel build --target node --experimental-scope-hoisting index.js",
"build-ts": "parcel build --target node index.js"
},
devDependencies: {
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0"
}
};
console.log(a.version);
})(); |
If I recall correctly, parcel's scope hoisting/shaking.js visitor only removes all unreferenced variables and doesn't go into the "object" level. Terser doesn't do it either, try it here: https://xem.github.io/terser-online/. |
Oh: terser can't optimize this (function() {
var a = {};
a = {
version: "1.2.3",
// ...
};
console.log(a.version);
})();
// result:
// no difference But only this: (function() {
var a = { // <---- no reassignment
version: "1.2.3",
// ...
};
console.log(a.version);
})();
// result:
console.log("1.2.3") Parcel's scope hoisting seems to always do this: var $ucH$exports = {};
$ucH$exports = {
// ...
} |
@mischnic that's probably because it can cause side-effects pretty easily |
But there aren't any with a JSON import, right? Ideally, there would be no extra // ---- source
module.exports = {
// json data
};
// ---- output
var $ucH$exports = {};
$ucH$exports = {
// json data
}; |
This wouldn't work with getters. --- a/packages/core/parcel-bundler/src/packagers/JSConcatPackager.js
+++ b/packages/core/parcel-bundler/src/packagers/JSConcatPackager.js
@@ -542,6 +542,11 @@ class JSConcatPackager extends Packager {
}
}
+ output = require("terser").minify(output, { // options from transforms/terser.js
+ warnings: true,
+ safari10: true,
+ }).code;
+
await super.write(output);
} |
We do
You can configure Terser by adding a |
Well, the (function () {console.log({});})(); |
How can terser do this already? As far as I can tell, only the assets are optimized by terser. This case can only be done by the packager |
Enabling
btw, Parcel uses Terser in a suboptimal way in order to improve build times. For smaller bundle size Terser should only be used once per bundle - not per JS asset with only a final mangle at the end.
Is this |
@fathyb @devongovett This has come up several times now. Are there any reasons not to do it this way? |
Last I checked it was much faster to run terser at the asset level and only mangle the top-level scope at the end rather than run terser over the final output, which could be huge. There also wasn't a very big difference in output size that I saw, but perhaps you've run into something. Did you try running terser over the final bundle to see if it got smaller? |
Mh, the only case where it helps seems to be this particular issue ("inlining a object.key lookup"). (In one project, the bundle was actually larger when removing the asset-level terser). |
See: #1685 (comment) Given:
Per-asset minification enabled yields a 1216 byte bundle:
Per-asset minification disabled - this unminified bundle size is not important:
Running that unminified bundle through terser mangle/compress yields a 564 byte bundle:
|
Some notes:
|
I've created a POC for testing: |
Rollup (REPL) handles this just fine (and the POC above as well), but I don't think they're using terser? import { cube } from './maths.js';
if(cube)
console.log("YES");
else
console.log("NO");
// maths.js
export const cube = false;
export const square = false; |
Thank you for the heads up about how Rollup handles this @mischnic |
@kzc What made the non-global terser invocation perform bad in this situations has been that Parcel didn't know about the As an alternative to running terser on the whole bundle, I made the scope hoisting algorithm be aware of these PURE comments (at its core a 3 line change). $ echo "var a = /*@__PURE__*/foobar();" | terser -c --comments "/__PURE__/"
var a=/* */foobar();
$ echo "var a = /*@__PURE__*/foobar();" | terser -c --comments "all"
var a=/* */foobar(); Can this be achieved with terser, WIP branch: https://github.com/parcel-bundler/parcel/compare/treeshake-pure |
I no longer work on terser. The pure annotation removal was intentionally introduced in uglify-js (and inherited by terser) to prevent the comments incorrectly shifting to non pure code after the compress pass and producing incorrect results. It was the simplest solution at the time to avoid some rather tricky corner cases. Rollup has also recently implemented uglify-js compatible pure annotations and incorporated the corresponding uglify-js tests. This PR discusses the issues involved in its implementation: rollup/rollup#2429 |
Thank you for your quick response
Makes sense.
My first idea was: 1) run terser on asset level 2) tree shake more intelligently using the pure comments to prevent running terser on the whole output. |
@mischnic I don't know where this issue stands and perhaps you guys found another solution with terser in the past couple of years, but I thought I'd pass on that |
Thanks. Parcel 2 already runs Terser at the end (so on the bundled output). Should be pretty easy to write an optimizer plugin that uses uglify-js instead, might be interesting to compare the two. |
@mischnic Cool. Please share your findings and open an issue with uglify-js if there's a problem. |
My project (a node web app) has a file (
config.js
) sitting at its root. It contains passwords, preferences etc. I would like to pull one of these into my front end js file that is being built with parcel but when it is built the entire config.js file copied to the output.For example:
in my code I expect to see the val
apdexT
but I see the entire contents of../../../config.js
Is there a way for the rest of the fie (that is not used in the file built with parcel) to be ignored?
Thank you in advance.
The text was updated successfully, but these errors were encountered: