metro upgrade

Summary: Upgrading to metro@0.45.3 and adapting to API changes made by metro.

Reviewed By: passy

Differential Revision: D9940734

fbshipit-source-id: 34b07cc70c9654d9e07755816aba703a826dcae9
This commit is contained in:
Daniel Büchele
2018-09-20 04:13:00 -07:00
committed by Facebook Github Bot
parent e763c5cd15
commit 2b4193a013
5 changed files with 1101 additions and 795 deletions

View File

@@ -9,7 +9,7 @@ const tmp = require('tmp');
const fs = require('fs-extra'); const fs = require('fs-extra');
const builder = require('electron-builder'); const builder = require('electron-builder');
const Platform = builder.Platform; const Platform = builder.Platform;
const metro = require('../static/node_modules/metro'); const Metro = require('../static/node_modules/metro');
const compilePlugins = require('../static/compilePlugins'); const compilePlugins = require('../static/compilePlugins');
function generateManifest(versionNumber) { function generateManifest(versionNumber) {
@@ -134,19 +134,32 @@ function compile(buildFolder) {
'Building main bundle', 'Building main bundle',
path.join(__dirname, '..', 'src', 'init.js'), path.join(__dirname, '..', 'src', 'init.js'),
); );
return metro const projectRoots = path.join(__dirname, '..');
.runBuild({ return Metro.runBuild(
config: { {
getProjectRoots: () => [path.join(__dirname, '..')], reporter: {update: () => {}},
getTransformModulePath: () => projectRoot: projectRoots,
path.join(__dirname, '..', 'static', 'transforms', 'index.js'), watchFolders: [projectRoots],
serializer: {},
transformer: {
babelTransformerPath: path.join(
__dirname,
'..',
'static',
'transforms',
'index.js',
),
}, },
resetCache: true, },
{
dev: false, dev: false,
minify: false,
resetCache: true,
sourceMap: true,
entry: path.join(__dirname, '..', 'src', 'init.js'), entry: path.join(__dirname, '..', 'src', 'init.js'),
out: path.join(buildFolder, 'bundle.js'), out: path.join(buildFolder, 'bundle.js'),
}) },
.catch(die); ).catch(die);
} }
function copyStaticFolder(buildFolder) { function copyStaticFolder(buildFolder) {

View File

@@ -14,7 +14,7 @@ const Convert = require('ansi-to-html');
const chalk = require('chalk'); const chalk = require('chalk');
const http = require('http'); const http = require('http');
const path = require('path'); const path = require('path');
const metro = require('../static/node_modules/metro'); const Metro = require('../static/node_modules/metro');
const fs = require('fs'); const fs = require('fs');
const convertAnsi = new Convert(); const convertAnsi = new Convert();
@@ -48,15 +48,23 @@ function launchElectron({bundleURL, electronURL}) {
}); });
} }
function startMetroServer(port) { function startMetroServer(app) {
return metro.runServer({ const projectRoot = path.join(__dirname, '..');
port, return Metro.runMetro({
watch: true, projectRoot,
config: { watchFolders: [projectRoot],
getProjectRoots: () => [path.join(__dirname, '..')], transformer: {
getTransformModulePath: () => babelTransformerPath: path.join(
path.join(__dirname, '..', 'static', 'transforms', 'index.js'), __dirname,
'..',
'static',
'transforms',
'index.js',
),
}, },
watch: true,
}).then(metroBundlerServer => {
app.use(metroBundlerServer.processRequest.bind(metroBundlerServer));
}); });
} }
@@ -88,7 +96,7 @@ function startAssetServer(port) {
const server = http.createServer(app); const server = http.createServer(app);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
server.listen(port, () => resolve(server)); server.listen(port, () => resolve({app, server}));
}); });
} }
@@ -162,14 +170,13 @@ function outputScreen(socket) {
} }
(async () => { (async () => {
const assetServerPort = await detect(DEFAULT_PORT); const port = await detect(DEFAULT_PORT);
const assetServer = await startAssetServer(assetServerPort); const {app, server} = await startAssetServer(port);
const socket = addWebsocket(assetServer); const socket = addWebsocket(server);
const metroServerPort = await detect(DEFAULT_PORT + 1); await startMetroServer(app);
await startMetroServer(metroServerPort);
outputScreen(socket); outputScreen(socket);
launchElectron({ launchElectron({
bundleURL: `http://localhost:${metroServerPort}/src/init.bundle`, bundleURL: `http://localhost:${port}/src/init.bundle`,
electronURL: `http://localhost:${assetServerPort}/index.dev.html`, electronURL: `http://localhost:${port}/index.dev.html`,
}); });
})(); })();

View File

@@ -7,28 +7,26 @@
const path = require('path'); const path = require('path');
const fs = require('fs'); const fs = require('fs');
const metro = require('metro'); const Metro = require('metro');
const util = require('util'); const util = require('util');
const recursiveReaddir = require('recursive-readdir'); const recursiveReaddir = require('recursive-readdir');
const HOME_DIR = require('os').homedir(); const HOME_DIR = require('os').homedir();
module.exports = (reloadCallback, pluginPaths, pluginCache) => { module.exports = async (reloadCallback, pluginPaths, pluginCache) => {
const plugins = pluginEntryPoints(pluginPaths); const plugins = pluginEntryPoints(pluginPaths);
if (!fs.existsSync(pluginCache)) { if (!fs.existsSync(pluginCache)) {
fs.mkdirSync(pluginCache); fs.mkdirSync(pluginCache);
} }
watchChanges(plugins, reloadCallback, pluginCache); watchChanges(plugins, reloadCallback, pluginCache);
return Promise.all( const dynamicPlugins = [];
Object.values(plugins).map(plugin => for (let plugin of Object.values(plugins)) {
compilePlugin(plugin, false, pluginCache), const compiledPlugin = await compilePlugin(plugin, false, pluginCache);
), if (compiledPlugin) {
) dynamicPlugins.push(compiledPlugin);
.then(dynamicPlugins => { }
// eslint-disable-next-line no-console }
console.log('✅ Compiled all plugins.'); console.log('✅ Compiled all plugins.');
return dynamicPlugins; return dynamicPlugins;
})
.catch(console.error);
}; };
function watchChanges(plugins, reloadCallback, pluginCache) { function watchChanges(plugins, reloadCallback, pluginCache) {
@@ -126,17 +124,6 @@ function entryPointForPluginFolder(pluginPath) {
return acc; return acc;
}, {}); }, {});
} }
function changeExport(path) {
let file = fs.readFileSync(path);
file = file
.toString()
.replace(
/\nrequire\((-?[0-9]+)\);\n*$/,
(_, moduleID) =>
`\nmodule.exports = global.require(${moduleID}).default;`,
);
fs.writeFileSync(path, file);
}
function mostRecentlyChanged(dir) { function mostRecentlyChanged(dir) {
return util return util
.promisify(recursiveReaddir)(dir) .promisify(recursiveReaddir)(dir)
@@ -146,53 +133,55 @@ function mostRecentlyChanged(dir) {
.reduce((a, b) => (a > b ? a : b), new Date(0)), .reduce((a, b) => (a > b ? a : b), new Date(0)),
); );
} }
function compilePlugin( async function compilePlugin(
{rootDir, name, entry, packageJSON}, {rootDir, name, entry, packageJSON},
force, force,
pluginCache, pluginCache,
) { ) {
return new Promise((resolve, reject) => {
const fileName = `${name}@${packageJSON.version || '0.0.0'}.js`; const fileName = `${name}@${packageJSON.version || '0.0.0'}.js`;
const out = path.join(pluginCache, fileName); const out = path.join(pluginCache, fileName);
const result = Object.assign({}, packageJSON, {rootDir, name, entry, out}); const result = Object.assign({}, packageJSON, {rootDir, name, entry, out});
// check if plugin needs to be compiled // check if plugin needs to be compiled
mostRecentlyChanged(rootDir).then(rootDirCtime => { const rootDirCtime = await mostRecentlyChanged(rootDir);
if ( if (!force && fs.existsSync(out) && rootDirCtime < fs.lstatSync(out).ctime) {
!force &&
fs.existsSync(out) &&
rootDirCtime < fs.lstatSync(out).ctime
) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(`🥫 Using cached version of ${name}...`); console.log(`🥫 Using cached version of ${name}...`);
resolve(result); return result;
} else { } else {
console.log(`⚙️ Compiling ${name}...`); // eslint-disable-line no-console console.log(`⚙️ Compiling ${name}...`); // eslint-disable-line no-console
metro try {
.runBuild({ await Metro.runBuild(
config: { {
getProjectRoots: () => [rootDir, path.join(__dirname, '..')], reporter: {update: () => {}},
getTransformModulePath: () => projectRoot: rootDir,
path.join(__dirname, 'transforms', 'index.js'), watchFolders: [__dirname, rootDir],
// a custom hash function is required, because by default metro starts serializer: {
// numbering the modules by 1. This means all plugins would start at getRunModuleStatement: moduleID =>
// ID 1, which causes a clash. This is why we have a custom IDFactory. `module.exports = global.__r(${moduleID}).default;`,
createModuleIdFactory, createModuleIdFactory,
}, },
dev: false, transformer: {
entry, babelTransformerPath: path.join(
__dirname,
'transforms',
'index.js',
),
},
},
{
entry: entry.replace(rootDir, '.'),
out, out,
}) dev: false,
.then(() => { sourceMap: true,
changeExport(out); },
resolve(result); );
}) } catch (e) {
.catch(err => {
console.error( console.error(
`❌ Plugin ${name} is ignored, because it could not be compiled.`, `❌ Plugin ${name} is ignored, because it could not be compiled.`,
); );
console.error(err); console.error(e);
}); return null;
}
return result;
} }
});
});
} }

View File

@@ -12,7 +12,7 @@
"babel-plugin-transform-object-rest-spread": "^7.0.0-beta.3", "babel-plugin-transform-object-rest-spread": "^7.0.0-beta.3",
"babel-preset-react": "^7.0.0-beta.3", "babel-preset-react": "^7.0.0-beta.3",
"babylon": "^7.0.0-beta.40", "babylon": "^7.0.0-beta.40",
"metro": "^0.28.0", "metro": "^0.45.3",
"recursive-readdir": "2.2.2" "recursive-readdir": "2.2.2"
} }
} }

File diff suppressed because it is too large Load Diff