diff --git a/packages/core/integration-tests/test/integration/process/index.js b/packages/core/integration-tests/test/integration/process/index.js new file mode 100644 index 00000000000..469e248a1e5 --- /dev/null +++ b/packages/core/integration-tests/test/integration/process/index.js @@ -0,0 +1,8 @@ +process.browser = false +module.exports = function () { + return process.browser && test(process.browser); +}; + +function test(val) { + return val; +} diff --git a/packages/core/integration-tests/test/javascript.js b/packages/core/integration-tests/test/javascript.js index 55286f20bea..c481b081df5 100644 --- a/packages/core/integration-tests/test/javascript.js +++ b/packages/core/integration-tests/test/javascript.js @@ -856,6 +856,45 @@ describe('javascript', function() { assert.equal(output, 'bartest'); }); + it('should replace process.browser on --target=browser', async function() { + let b = await bundle( + path.join(__dirname, '/integration/process/index.js'), + { + target: 'browser' + } + ); + + let output = await run(b); + assert.ok(output.toString().indexOf('process.browser') === -1); + assert.equal(output(), true); + }); + + it('should not replace process.browser on --target=node', async function() { + let b = await bundle( + path.join(__dirname, '/integration/process/index.js'), + { + target: 'node' + } + ); + + let output = await run(b); + assert.ok(output.toString().indexOf('process.browser') !== -1); + assert.equal(output(), false); + }); + + it('should not replace process.browser on --target=electron', async function() { + let b = await bundle( + path.join(__dirname, '/integration/process/index.js'), + { + target: 'electron' + } + ); + + let output = await run(b); + assert.ok(output.toString().indexOf('process.browser') !== -1); + assert.equal(output(), false); + }); + it('should support adding implicit dependencies', async function() { let b = await bundle(path.join(__dirname, '/integration/json/index.js'), { delegate: { diff --git a/packages/core/parcel-bundler/src/assets/JSAsset.js b/packages/core/parcel-bundler/src/assets/JSAsset.js index 1e1b9308a80..e300a07e8ba 100644 --- a/packages/core/parcel-bundler/src/assets/JSAsset.js +++ b/packages/core/parcel-bundler/src/assets/JSAsset.js @@ -7,6 +7,7 @@ const babelParser = require('@babel/parser'); const insertGlobals = require('../visitors/globals'); const fsVisitor = require('../visitors/fs'); const envVisitor = require('../visitors/env'); +const processVisitor = require('../visitors/process'); const babel = require('../transforms/babel/transform'); const babel7 = require('../transforms/babel/babel7'); const generate = require('@babel/generator').default; @@ -20,6 +21,7 @@ const isAccessedVarChanged = require('../utils/isAccessedVarChanged'); const IMPORT_RE = /\b(?:import\b|export\b|require\s*\()/; const ENV_RE = /\b(?:process\.env)\b/; +const BROWSER_RE = /\b(?:process\.browser)\b/; const GLOBAL_RE = /\b(?:process|__dirname|__filename|global|Buffer|define)\b/; const FS_RE = /\breadFileSync\b/; const SW_RE = /\bnavigator\s*\.\s*serviceWorker\s*\.\s*register\s*\(/; @@ -155,6 +157,13 @@ class JSAsset extends Asset { await this.parseIfNeeded(); this.traverseFast(envVisitor); } + + // Inline process.browser + if (this.options.target === 'browser' && BROWSER_RE.test(this.contents)) { + await this.parseIfNeeded(); + this.traverse(processVisitor); + this.isAstDirty = true; + } } async transform() { diff --git a/packages/core/parcel-bundler/src/visitors/process.js b/packages/core/parcel-bundler/src/visitors/process.js new file mode 100644 index 00000000000..4a3c209b9cd --- /dev/null +++ b/packages/core/parcel-bundler/src/visitors/process.js @@ -0,0 +1,17 @@ +const t = require('@babel/types'); + +module.exports = { + MemberExpression(path) { + // Inline process.browser + const isProcess = path.node.object.name === 'process'; + const isBrowser = path.node.property.name === 'browser'; + const isAssignment = path.parentPath.type === 'AssignmentExpression'; + if (isProcess && isBrowser) { + if (isAssignment) { + path.parentPath.remove(); + } else { + path.replaceWith(t.booleanLiteral(true)); + } + } + } +};