Skip to content

Commit

Permalink
Don't inline env vars & fs (parcel-bundler#4993)
Browse files Browse the repository at this point in the history
  • Loading branch information
mischnic authored Aug 18, 2020
1 parent 64ebc37 commit 7dccaa6
Show file tree
Hide file tree
Showing 30 changed files with 361 additions and 114 deletions.
1 change: 1 addition & 0 deletions packages/bundlers/default/src/DefaultBundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ const CONFIG_SCHEMA: SchemaEntity = {
type: 'number',
},
},
additionalProperties: false,
};

async function loadBundlerConfig(options: PluginOptions) {
Expand Down
3 changes: 3 additions & 0 deletions packages/core/core/src/TargetDescriptor.schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ export const DESCRIPTOR_SCHEMA: SchemaEntity = {
minify: {
type: 'boolean',
},
scopeHoist: {
type: 'boolean',
},
},
additionalProperties: false,
};
Expand Down
14 changes: 2 additions & 12 deletions packages/core/integration-tests/test/blob-url.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,11 @@

import assert from 'assert';
import path from 'path';
import {bundle, distDir, outputFS, inputFS} from '@parcel/test-utils';

const configPath = path.join(__dirname, '/integration/blob-url/.parcelrc');

const config = {
...JSON.parse(inputFS.readFileSync(configPath, 'utf8')),
filePath: configPath,
};
import {bundle, distDir, outputFS} from '@parcel/test-utils';

describe('blob urls', () => {
it('should inline compiled content as a blob url with `blob-url:*` imports', async () => {
await bundle(path.join(__dirname, '/integration/blob-url/index.js'), {
config,
});
await bundle(path.join(__dirname, '/integration/blob-url/index.js'));

let bundleContent = await outputFS.readFile(
path.join(distDir, 'index.js'),
Expand All @@ -36,7 +27,6 @@ describe('blob urls', () => {

it('should inline minified content as a blob url with `blob-url:*` imports', async () => {
await bundle(path.join(__dirname, '/integration/blob-url/index.js'), {
config,
minify: true,
});

Expand Down
34 changes: 33 additions & 1 deletion packages/core/integration-tests/test/fs.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// @flow
import assert from 'assert';
import path from 'path';
import {
assertBundles,
bundle,
removeDistDirectory,
run,
overlayFS,
outputFS,
distDir,
} from '@parcel/test-utils';
Expand All @@ -15,6 +17,36 @@ describe('fs', function() {
});

describe('browser environment', function() {
it('should not inline a file if disabled via config', async function() {
let b = await bundle(
path.join(__dirname, '/integration/fs-disabled/index.js'),
{
inputFS: overlayFS,
},
);

// $FlowFixMe
await assert.rejects(() => run(b), {
message: `ENOENT: no such file or directory, open '...'`,
code: 'ENOENT',
});
});

it('should not inline a file outside of the project root', async function() {
let b = await bundle(
path.join(__dirname, '/integration/fs-outside-root/index.js'),
{
inputFS: overlayFS,
},
);

// $FlowFixMe
await assert.rejects(() => run(b), {
message: `ENOENT: no such file or directory, open '...'`,
code: 'ENOENT',
});
});

it('should inline a file as a string', async function() {
let b = await bundle(path.join(__dirname, '/integration/fs/index.js'));
let output = await run(b);
Expand Down Expand Up @@ -198,7 +230,7 @@ describe('fs', function() {
describe.skip('electron environment', function() {
it('should not inline a file in an Electron environment', async function() {
let b = await bundle(path.join(__dirname, '/integration/fs/index.js'), {
target: 'electron',
targets: ['electron'],
});

assertBundles(b, [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = function () {
return process.env.A_1 + ":" + process.env.B_1 + ":" + process.env.B_2;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@parcel/transformer-js": {
"inlineEnvironment": ["B_*"]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = function () {
return process.env.FOOBAR + test(process.env.FOOBAR);
};

function test(str) {
return ':' + str;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@parcel/transformer-js": {
"inlineEnvironment": false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = function () {
return process.env.NODE_ENV + ":" + process.env.FOO;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@parcel/transformer-js": {
"inlineEnvironment": false
}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = function insertEnv(babel) {
const exportFoo = babel.template('module.exports = process.env.foo;');
const exportFoo = babel.template('module.exports = process.env.NODE_ENV;', {syntacticPlaceholders: true});

return {
visitor: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var fs = require('fs');
module.exports = fs.readFileSync(__dirname + '/test.txt', 'utf8');
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@parcel/transformer-js": {
"inlineFS": false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
var fs = require('fs');

fs.readFileSync(__dirname + '../../../../../../../package.json', 'utf8')

63 changes: 53 additions & 10 deletions packages/core/integration-tests/test/javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -1238,10 +1238,10 @@ describe('javascript', function() {
);

let jsBundle = b.getBundles()[0];
let contents = await outputFS.readFile(jsBundle.filePath);
let contents = await outputFS.readFile(jsBundle.filePath, 'utf8');

assert(!contents.includes('process.env'));
assert.equal(await run(b), 42);
assert.equal(await run(b), 'test');
});

it('should not insert environment variables in node environment', async function() {
Expand All @@ -1250,7 +1250,7 @@ describe('javascript', function() {
);

let output = await run(b);
assert.ok(output.toString().indexOf('process.env') > -1);
assert.ok(output.toString().includes('process.env'));
assert.equal(output(), 'test:test');
});

Expand All @@ -1265,7 +1265,7 @@ describe('javascript', function() {
});

let output = await run(b);
assert.ok(output.toString().indexOf('process.env') > -1);
assert.ok(output.toString().includes('process.env'));
assert.equal(output(), 'test:test');
});

Expand All @@ -1280,16 +1280,59 @@ describe('javascript', function() {
});

let output = await run(b);
assert.ok(output.toString().indexOf('process.env') > -1);
assert.ok(output.toString().includes('process.env'));
assert.equal(output(), 'test:test');
});

it('should insert environment variables in browser environment', async function() {
let b = await bundle(path.join(__dirname, '/integration/env/index.js'));
it('should inline NODE_ENV environment variable in browser environment even if disabled', async function() {
let b = await bundle(
path.join(__dirname, '/integration/env-nodeenv/index.js'),
{
env: {
FOO: 'abc',
},
},
);

let output = await run(b);
assert.ok(output.toString().indexOf('process.env') === -1);
assert.equal(output(), 'test:test');
assert.ok(!output.toString().includes('process.env'));
assert.equal(output(), 'test:undefined');
});

it('should not insert environment variables in browser environment if disabled', async function() {
let b = await bundle(
path.join(__dirname, '/integration/env-disabled/index.js'),
{
env: {FOOBAR: 'abc'},
},
);

let output = await run(b);
assert.ok(!output.toString().includes('process.env'));
assert.equal(output(), 'undefined:undefined');
});

it('should only insert environment variables in browser environment matching the glob', async function() {
let b = await bundle(
path.join(__dirname, '/integration/env-disabled-glob/index.js'),
{
env: {A_1: 'abc', B_1: 'def', B_2: 'ghi'},
},
);

let output = await run(b);
assert.ok(!output.toString().includes('process.env'));
assert.equal(output(), 'undefined:def:ghi');
});

it('should be able to inline environment variables in browser environment', async function() {
let b = await bundle(path.join(__dirname, '/integration/env/index.js'), {
env: {NODE_ENV: 'abc'},
});

let output = await run(b);
assert.ok(!output.toString().includes('process.env'));
assert.equal(output(), 'abc:abc');
});

it("should insert the user's NODE_ENV as process.env.NODE_ENV if passed", async function() {
Expand All @@ -1300,7 +1343,7 @@ describe('javascript', function() {
});

let output = await run(b);
assert.ok(output.toString().indexOf('process.env') === -1);
assert.ok(!output.toString().includes('process.env'));
assert.equal(output(), 'production:production');
});

Expand Down
2 changes: 1 addition & 1 deletion packages/core/test-utils/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export async function run(
bundleGraph: BundleGraph<NamedBundle>,
globals: mixed,
opts: RunOpts = {},
): Promise<mixed> {
): Promise<any> {
let bundles = bundleGraph.getBundles();
let bundle = nullthrows(
bundles.find(b => b.type === 'js' || b.type === 'html'),
Expand Down
29 changes: 28 additions & 1 deletion packages/shared/babel-ast-utils/src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
// @flow strict-local

import type {AST, BaseAsset, PluginOptions} from '@parcel/types';
import type {
AST,
BaseAsset,
PluginOptions,
SourceLocation,
} from '@parcel/types';
import type {SourceLocation as BabelSourceLocation} from '@babel/types';

import path from 'path';
import babelGenerate from '@babel/generator';
import {parse as babelParse} from '@babel/parser';
import SourceMap from '@parcel/source-map';
Expand Down Expand Up @@ -73,3 +80,23 @@ export async function generate({
map,
};
}

export function convertBabelLoc(loc: ?BabelSourceLocation): ?SourceLocation {
if (!loc) return null;
let {filename, start, end} = loc;
if (filename == null) return null;
return {
filePath: path.normalize(filename),
start: {
line: start.line,
column: start.column + 1,
},
// - Babel's columns are exclusive, ours are inclusive (column - 1)
// - Babel has 0-based columns, ours are 1-based (column + 1)
// = +-0
end: {
line: end.line,
column: end.column,
},
};
}
1 change: 1 addition & 0 deletions packages/shared/scope-hoisting/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@babel/template": "^7.2.2",
"@babel/traverse": "^7.2.3",
"@babel/types": "^7.3.3",
"@parcel/babel-ast-utils": "2.0.0-beta.1",
"@parcel/babylon-walk": "2.0.0-beta.1",
"@parcel/diagnostic": "2.0.0-beta.1",
"@parcel/source-map": "2.0.0-alpha.4.13",
Expand Down
8 changes: 2 additions & 6 deletions packages/shared/scope-hoisting/src/hoist.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,9 @@ import traverse from '@babel/traverse';
import template from '@babel/template';
import nullthrows from 'nullthrows';
import invariant from 'assert';
import {convertBabelLoc} from '@parcel/babel-ast-utils';
import rename from './renamer';
import {
convertBabelLoc,
getName,
getIdentifier,
getExportIdentifier,
} from './utils';
import {getName, getIdentifier, getExportIdentifier} from './utils';

const WRAPPER_TEMPLATE = template.statement<
{|NAME: LVal, BODY: Array<Statement>|},
Expand Down
6 changes: 3 additions & 3 deletions packages/shared/scope-hoisting/src/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ import {
isSequenceExpression,
isStringLiteral,
} from '@babel/types';
import {convertBabelLoc} from '@parcel/babel-ast-utils';
import traverse from '@babel/traverse';
import treeShake from './shake';
import {
assertString,
convertBabelLoc,
getName,
getIdentifier,
getThrowableDiagnosticForNode,
Expand Down Expand Up @@ -525,7 +525,7 @@ export function link({
throw getThrowableDiagnosticForNode(
"`require.resolve` calls for excluded assets are only supported with outputFormat: 'commonjs'",
mapped.filePath,
path.node.loc,
convertBabelLoc(path.node.loc),
);
}
Expand All @@ -536,7 +536,7 @@ export function link({
throw getThrowableDiagnosticForNode(
"`require.resolve` calls for bundled modules or bundled assets aren't supported with scope hoisting",
mapped.filePath,
path.node.loc,
convertBabelLoc(path.node.loc),
);
}
}
Expand Down
Loading

0 comments on commit 7dccaa6

Please sign in to comment.