diff --git a/packages/metro/src/Bundler.js b/packages/metro/src/Bundler.js index 90e4112a..de6707fa 100644 --- a/packages/metro/src/Bundler.js +++ b/packages/metro/src/Bundler.js @@ -217,7 +217,6 @@ class Bundler { async _cachedTransformCode( module: Module, - code: ?string, transformCodeOptions: WorkerOptions, ): Promise { const cache = this._cache; @@ -229,6 +228,7 @@ class Bundler { dev, hot, inlineRequires, + isScript, minify, platform, projectRoot: _projectRoot, // Blacklisted property. @@ -257,6 +257,7 @@ class Bundler { dev, hot, inlineRequires, + isScript, minify, platform, ]); @@ -272,8 +273,6 @@ class Bundler { : await this._transformer.transform( module.path, module.localPath, - code, - module.isPolyfill(), transformCodeOptions, this._opts.assetExts, this._opts.assetRegistryPath, diff --git a/packages/metro/src/Bundler/__tests__/Bundler-test.js b/packages/metro/src/Bundler/__tests__/Bundler-test.js index 40223a95..567c9349 100644 --- a/packages/metro/src/Bundler/__tests__/Bundler-test.js +++ b/packages/metro/src/Bundler/__tests__/Bundler-test.js @@ -127,7 +127,7 @@ describe('Bundler', function() { result: {}, }); - await bundlerInstance._cachedTransformCode(module, null, {}); + await bundlerInstance._cachedTransformCode(module, {}); // We got the SHA-1 of the file from the dependency graph. expect(depGraph.getSha1).toBeCalledWith('/root/foo.js'); diff --git a/packages/metro/src/JSTransformer.js b/packages/metro/src/JSTransformer.js index 7c65b822..0557b2f1 100644 --- a/packages/metro/src/JSTransformer.js +++ b/packages/metro/src/JSTransformer.js @@ -86,8 +86,6 @@ module.exports = class Transformer { async transform( filename: string, localPath: LocalPath, - code: ?string, - isScript: boolean, options: WorkerOptions, assetExts: $ReadOnlyArray, assetRegistryPath: string, @@ -99,9 +97,7 @@ module.exports = class Transformer { const data = await this._worker.transform( filename, localPath, - code, this._transformModulePath, - isScript, options, assetExts, assetRegistryPath, diff --git a/packages/metro/src/JSTransformer/__tests__/Transformer-test.js b/packages/metro/src/JSTransformer/__tests__/Transformer-test.js index af26bcee..6dddd29a 100644 --- a/packages/metro/src/JSTransformer/__tests__/Transformer-test.js +++ b/packages/metro/src/JSTransformer/__tests__/Transformer-test.js @@ -68,13 +68,10 @@ describe('Transformer', function() { it('passes transform data to the worker farm when transforming', async () => { const transformOptions = {arbitrary: 'options'}; - const code = 'arbitrary(code)'; await new Transformer(opts).transform( fileName, localPath, - code, - false, transformOptions, [], '', @@ -84,9 +81,7 @@ describe('Transformer', function() { expect(api.transform).toBeCalledWith( fileName, localPath, - code, transformModulePath, - false, transformOptions, [], '', @@ -102,7 +97,7 @@ describe('Transformer', function() { const snippet = 'snippet'; api.transform.mockImplementation( - (filename, localPth, code, transformPath, opts) => { + (filename, localPth, transformPath, opts) => { const babelError = new SyntaxError(message); babelError.type = 'SyntaxError'; diff --git a/packages/metro/src/JSTransformer/worker.js b/packages/metro/src/JSTransformer/worker.js index 502c7d50..49f44359 100644 --- a/packages/metro/src/JSTransformer/worker.js +++ b/packages/metro/src/JSTransformer/worker.js @@ -78,6 +78,7 @@ export type WorkerOptions = {| +dev: boolean, +hot: boolean, +inlineRequires: boolean, + +isScript: boolean, +minify: boolean, +platform: ?string, +projectRoot: string, @@ -124,9 +125,7 @@ function getDynamicDepsBehavior( async function transformCode( filename: string, localPath: LocalPath, - sourceCode: ?string, transformerPath: string, - isScript: boolean, options: WorkerOptions, assetExts: $ReadOnlyArray, assetRegistryPath: string, @@ -142,17 +141,13 @@ async function transformCode( start_timestamp: process.hrtime(), }; - let data; + const data = fs.readFileSync(filename); + const sourceCode = data.toString('utf8'); let type = 'js/module'; - if (sourceCode == null) { - data = fs.readFileSync(filename); - sourceCode = data.toString('utf8'); - } - const sha1 = crypto .createHash('sha1') - .update(data || sourceCode) + .update(data) .digest('hex'); if (filename.endsWith('.json')) { @@ -226,7 +221,7 @@ async function transformCode( // dependency graph and it code will just be prepended to the bundle modules), // we need to wrap it differently than a commonJS module (also, scripts do // not have dependencies). - if (isScript) { + if (options.isScript) { dependencies = []; wrappedAst = JsFileWrapping.wrapPolyfill(ast); diff --git a/packages/metro/src/JSTransformer/worker/__tests__/__snapshots__/worker-test.js.snap b/packages/metro/src/JSTransformer/worker/__tests__/__snapshots__/worker-test.js.snap index b8874390..4d0f5d30 100644 --- a/packages/metro/src/JSTransformer/worker/__tests__/__snapshots__/worker-test.js.snap +++ b/packages/metro/src/JSTransformer/worker/__tests__/__snapshots__/worker-test.js.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`code transformation worker: reports filename when encountering unsupported dynamic dependency 1`] = `"arbitrary/file.js:3:10: calls to \`require\` expect exactly 1 string literal argument, but this was found: \`require(a)\`."`; +exports[`code transformation worker: reports filename when encountering unsupported dynamic dependency 1`] = `"/root/local/file.js:3:10: calls to \`require\` expect exactly 1 string literal argument, but this was found: \`require(a)\`."`; diff --git a/packages/metro/src/JSTransformer/worker/__tests__/worker-test.js b/packages/metro/src/JSTransformer/worker/__tests__/worker-test.js index 3c81636f..aeb25096 100644 --- a/packages/metro/src/JSTransformer/worker/__tests__/worker-test.js +++ b/packages/metro/src/JSTransformer/worker/__tests__/worker-test.js @@ -21,19 +21,45 @@ jest .mock('metro-minify-uglify'); const path = require('path'); -const transformCode = require('..').transform; -const {InvalidRequireCallError} = require('..'); + +const transformerPath = require.resolve('metro/src/transformer.js'); +const transformerContents = require('fs').readFileSync(transformerPath); + +const babelRcPath = require.resolve('metro/rn-babelrc.json'); +const babelRcContents = require('fs').readFileSync(babelRcPath); + +let fs; +let mkdirp; +let transformCode; +let InvalidRequireCallError; describe('code transformation worker:', () => { + beforeEach(() => { + jest.resetModules(); + + jest.mock('fs', () => new (require('metro-memory-fs'))()); + + fs = require('fs'); + mkdirp = require('mkdirp'); + ({transform: transformCode, InvalidRequireCallError} = require('..')); + fs.reset(); + + mkdirp.sync('/root/local'); + mkdirp.sync(path.dirname(transformerPath)); + fs.writeFileSync(transformerPath, transformerContents); + fs.writeFileSync(babelRcPath, babelRcContents); + }); + it('transforms a simple script', async () => { + fs.writeFileSync('/root/local/file.js', 'someReallyArbitrary(code)'); + const {result} = await transformCode( - 'arbitrary/file.js', + '/root/local/file.js', `local/file.js`, - 'someReallyArbitrary(code)', - require.resolve('metro/src/transformer.js'), - true, + transformerPath, { dev: true, + isScript: true, transform: {}, }, [], @@ -56,14 +82,15 @@ describe('code transformation worker:', () => { }); it('transforms a simple module', async () => { + fs.writeFileSync('/root/local/file.js', 'arbitrary(code)'); + const {result} = await transformCode( - 'arbitrary/file.js', + '/root/local/file.js', `local/file.js`, - 'arbitrary(code)', - require.resolve('metro/src/transformer.js'), - false, + transformerPath, { dev: true, + isScript: false, transform: {}, }, [], @@ -86,9 +113,8 @@ describe('code transformation worker:', () => { }); it(`transforms a module with dependencies`, async () => { - const {result} = await transformCode( - 'arbitrary/file.js', - `local/file.js`, + fs.writeFileSync( + '/root/local/file.js', [ "'use strict';", 'require("./a");', @@ -96,8 +122,12 @@ describe('code transformation worker:', () => { 'const b = require("b");', 'import c from "./c";', ].join('\n'), - require.resolve('metro/src/transformer.js'), - false, + ); + + const {result} = await transformCode( + '/root/local/file.js', + `local/file.js`, + transformerPath, { dev: true, transform: {}, @@ -134,17 +164,20 @@ describe('code transformation worker:', () => { }); it('reports filename when encountering unsupported dynamic dependency', async () => { + fs.writeFileSync( + '/root/local/file.js', + [ + 'require("./a");', + 'let a = arbitrary(code);', + 'const b = require(a);', + ].join('\n'), + ); + try { await transformCode( - 'arbitrary/file.js', + '/root/local/file.js', `local/file.js`, - [ - 'require("./a");', - 'let a = arbitrary(code);', - 'const b = require(a);', - ].join('\n'), - path.join(__dirname, '../../../transformer.js'), - false, + transformerPath, { dev: true, transform: {}, @@ -165,12 +198,13 @@ describe('code transformation worker:', () => { }); it('supports dynamic dependencies from within `node_modules`', async () => { + mkdirp.sync('/root/node_modules/foo'); + fs.writeFileSync('/root/node_modules/foo/bar.js', 'require(foo.bar);'); + await transformCode( - '/root/node_modules/bar/file.js', - `node_modules/bar/file.js`, - 'require(global.something);\n', - path.join(__dirname, '../../../transformer.js'), - false, + '/root/node_modules/foo/bar.js', + `node_modules/foo/bar.js`, + transformerPath, { dev: true, transform: {}, @@ -185,13 +219,13 @@ describe('code transformation worker:', () => { }); it('minifies the code correctly', async () => { + fs.writeFileSync('/root/local/file.js', 'arbitrary(code);'); + expect( (await transformCode( - '/root/node_modules/bar/file.js', - `node_modules/bar/file.js`, - 'arbitrary(code);', - path.join(__dirname, '../../../transformer.js'), - false, + '/root/local/file.js', + `local/file.js`, + transformerPath, { dev: true, minify: true, @@ -214,13 +248,13 @@ describe('code transformation worker:', () => { }); it('minifies a JSON file', async () => { + fs.writeFileSync('/root/local/file.json', 'arbitrary(code);'); + expect( (await transformCode( - '/root/node_modules/bar/file.json', - `node_modules/bar/file.js`, - 'arbitrary(code);', - path.join(__dirname, '../../../transformer.js'), - false, + '/root/local/file.json', + `local/file.json`, + transformerPath, { dev: true, minify: true, diff --git a/packages/metro/src/lib/transformHelpers.js b/packages/metro/src/lib/transformHelpers.js index 3d8c23f4..75d58b29 100644 --- a/packages/metro/src/lib/transformHelpers.js +++ b/packages/metro/src/lib/transformHelpers.js @@ -36,6 +36,7 @@ async function calcTransformerOptions( dev: options.dev, hot: options.hot, inlineRequires: false, + isScript: options.type === 'script', minify: options.minify, platform: options.platform, projectRoot, diff --git a/packages/metro/src/node-haste/Module.js b/packages/metro/src/node-haste/Module.js index a9e8e58f..307748ad 100644 --- a/packages/metro/src/node-haste/Module.js +++ b/packages/metro/src/node-haste/Module.js @@ -24,7 +24,6 @@ type ReadResult = { export type TransformCode = ( module: Module, - sourceCode: ?string, transformOptions: WorkerOptions, ) => Promise; @@ -74,7 +73,6 @@ class Module { async read(transformOptions: WorkerOptions): Promise { const result: TransformedCode = await this._transformCode( this, - null, // Source code is read on the worker transformOptions, );