Skip to content

Commit

Permalink
wip: improvements to with-react-native
Browse files Browse the repository at this point in the history
Added an `rn:dev` field since the metro bundler can't work with preconstruct symlinks in dev mode
  • Loading branch information
ifiokjr committed Jan 28, 2021
1 parent 26b5def commit eed8b71
Show file tree
Hide file tree
Showing 135 changed files with 1,056 additions and 753 deletions.
2 changes: 1 addition & 1 deletion examples/with-react-native/android/build.gradle
Expand Up @@ -3,7 +3,7 @@
buildscript {
ext {
buildToolsVersion = "29.0.2"
minSdkVersion = 16
minSdkVersion = 21
compileSdkVersion = 29
targetSdkVersion = 29
}
Expand Down
@@ -1,6 +1,6 @@
#Wed Jan 27 12:07:19 GMT 2021
#Wed Jan 27 20:40:12 GMT 2021
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
5 changes: 4 additions & 1 deletion examples/with-react-native/babel.config.js
@@ -1,3 +1,6 @@
const config = require('../../support/base.babel');

module.exports = {
presets: ['module:metro-react-native-babel-preset'],
...config,
presets: [...config.presets, 'module:metro-react-native-babel-preset', '@linaria'],
};
182 changes: 62 additions & 120 deletions examples/with-react-native/metro.config.js
@@ -1,74 +1,35 @@
const path = require('path');
const { FileStore } = require('metro-cache');
const findCacheDir = require('find-cache-dir');
const blacklist = require('metro-config/src/defaults/blacklist');
const findUp = require('find-up');
const leftPad = require('left-pad');
const Metro = require('metro-core');
const resolveFrom = require('resolve-from');
const exclusionList = require('metro-config/src/defaults/blacklist');
const {
NodeJsInputFileSystem,
CachedInputFileSystem,
ResolverFactory,
} = require('enhanced-resolve');
const fs = require('fs');

// Time tranformation of each file.
// From https://github.com/facebook/metro/issues/253#issuecomment-422084406

Metro.Logger.on('log', (logEntry) => {
if (logEntry.action_name === 'Transforming file' && logEntry.action_phase === 'end') {
console.log(leftPad(parseInt(logEntry.duration_ms), 4), logEntry.file_name);
}
});

// Paths
////////////////////

const projectRoot = process.cwd();

// Config
////////////////////

// Disabled because we are using `unsafeCache` (disk cache) now.
const useResolveFrom = false;
const useCache = true;

// Caching
////////////////////

const cacheFile = findCacheDir({
name: 'metro-resolver-webpack-custom',
thunk: true,
create: true,
});

// Caching
////////////////////

const cacheFileStore = new FileStore({
root: findCacheDir({ name: 'metro-custom', create: true }),
});

// Resolving
////////////////////

let resolveCtx = {};
const resolveCtx = {};
const resolveRequest = makeResolveRequest(resolveCtx);

////////////////////

//let expoAssetPluginPath = require.resolve(
// path.join(projectRoot, 'node_modules/expo/tools/hashAssetFiles'),
//)

// Blacklist
////////////////////

let customBlacklist = [/.*\/nest-orig\/.*/];

////////////////////

// See https://facebook.github.io/metro/docs/en/configuration.
function getConfig() {
return {
Expand All @@ -82,8 +43,7 @@ function getConfig() {
path.join(path.resolve(projectRoot), 'node_modules'),

/*
Only needed for pnpm monorepo usage
To avoid the following error we must add the repo root:
Only needed for pnpm monorepo usage To avoid the following error we must add the repo root:
```
Expected path `/xxx/node_modules/.registry.npmjs.org/@babel/runtime/7.2.0/node_modules/@babel/runtime/helpers/interopRequireDefault.js` to be relative to one of the project roots
```
Expand All @@ -98,84 +58,54 @@ function getConfig() {

//cacheVersion,

//resetCache,
resetCache: true,

// Reporting
////////////////////////////////////////////////////////////////////////////

// See https://github.com/facebook/metro/blob/92f8e5deee2fb574ccf68d7ce4de5fecf7477df6/packages/metro/src/lib/reporting.js#L32
reporter: {
update: (event) => {
console.log(event);
resolveCtx.onReporterUpdate && resolveCtx.onReporterUpdate(event);
},
},

server: {
//enhanceMiddleware: (middlware, server) => middleware,
//enableVisualizer: true, // Install `metro-visualizer`.
},
// See
// https://github.com/facebook/metro/blob/92f8e5deee2fb574ccf68d7ce4de5fecf7477df6/packages/metro/src/lib/reporting.js#L32
// reporter: {update: (event) => {console.log(event); resolveCtx.onReporterUpdate &&
// resolveCtx.onReporterUpdate(event);
// },
// },

// Transformer
////////////////////////////////////////////////////////////////////////////
server: {},

transformer: {
// Because react-native (expo fork?) fails to resolve it unless we install expo in the repo root.
// https://github.com/pnpm/pnpm/issues/1501#issuecomment-446699920
// TODO(vjpr): Although this is bad because it prevents using multiple versions across projects.
//assetPlugins: [expoAssetPluginPath],

// Transformer Paths
////////////////////

// From: https://github.com/facebook/metro/blob/master/packages/metro-config/src/defaults/index.js

workerPath: getWorkerPath(),
//asyncRequireModulePath: 'metro-runtime/src/modules/asyncRequire',
//assetRegistryPath: 'missing-asset-registry-path',
//babelTransformerPath: 'metro-babel-transformer',
//transformerPath: require.resolve('metro-transform-worker'),
//minifierPath: 'metro-minify-uglify',

////////////////////

//enableBabelRCLookup,

//enableBabelRuntime
},

// Resolver
////////////////////////////////////////////////////////////////////////////

resolver: {
blacklistRE: blacklist([/.*\/default\/.*/, /.*\/\.cache\/.*/, ...customBlacklist]),

blacklistRE: exclusionList([/.*\/default\/.*/, /.*\/\.cache\/.*/, /.*\/nest-orig\/.*/]),
extraNodeModules: {},

// NOTE: This will run for all files if watchman fails to start.
resolveRequest,
// --

resolverMainFields: ['rn:dev', 'react-native', 'browser', 'module', 'main'],
sourceExts: ['js', 'json', 'ts', 'tsx', 'cjs', 'mjs', 'jsx'],

useWatchman: false,

// TODO(vjpr): Could use this perhaps instead of patching.
// Although I think I looked into this and it was not possible.
//hasteImplModulePath,
// TODO(vjpr): Could use this perhaps instead of patching. Although I think I looked into this
// and it was not possible. hasteImplModulePath,
},
};
}

module.exports = getConfig();

function getRepoRoot() {
return path.dirname(findUp.sync('pnpm-workspace.yaml', { cwd: process.cwd() }));
}

function getWorkerPath() {
// The default is set in https://github.com/facebook/metro/blob/d6eefe44bdc163c04b3ada92d825451b52ecf41a/packages/metro-config/src/defaults/index.js#L116
// The default is set in
// https://github.com/facebook/metro/blob/d6eefe44bdc163c04b3ada92d825451b52ecf41a/packages/metro-config/src/defaults/index.js#L116
// As of 202012, it is 'metro/src/DeltaBundler/Worker'.
const workerPath =
'/node_modules/.pnpm/metro@0.58.0/node_modules/metro/src/DeltaBundler/Worker.js';
const workerPath = '/examples/with-react-native/node_modules/metro/src/DeltaBundler/Worker.js';
const repoRoot = getRepoRoot();
return require.resolve(path.join(repoRoot, workerPath));
}
Expand All @@ -184,27 +114,26 @@ function makeResolveRequest(resolveCtx) {
//////////////////////////////////////////////////////////////////////////////

// TODO(vjpr): Change tmp file name to node_modules.
let cacheFilename = cacheFile('cache.json');
const cacheFilename = cacheFile('cache.json');
let cache;
try {
cache = JSON.parse(fs.readFileSync(cacheFilename, 'utf8'));
} catch (e) {
if (!e.code === 'ENOENT') {
console.log(`cache read error:`, e);
} catch (error) {
if (!error.code === 'ENOENT') {
console.log(`cache read error:`, error);
}
}
if (!cache) cache = {};

if (!cache) {
cache = {};
}

if (useCache) {
// a.
// TODO(vjpr): Find a better way to save.
//process.on('exit', () => {save()})
// a. TODO(vjpr): Find a better way to save. process.on('exit', () => {save()})

//setInterval(() => {save()}, 10000)

// NOTE(vjpr): Runs too soon.
//process.nextTick(() => {
// save()
// NOTE(vjpr): Runs too soon. process.nextTick(() => {save()
//})

resolveCtx.onReporterUpdate = (event) => {
Expand All @@ -214,16 +143,17 @@ function makeResolveRequest(resolveCtx) {
};

// TODO(vjpr): Maybe there is a hook we can use. After compile?
}

function save() {
console.log('saving resolver cache');
fs.writeFileSync(cacheFilename, JSON.stringify(cache, null, 2));
}
function save() {
console.log('saving resolver cache');
fs.writeFileSync(cacheFilename, JSON.stringify(cache, null, 2));
}

//////////////////////////////////////////////////////////////////////////////

// Typical usage will consume the `NodeJsInputFileSystem` + `CachedInputFileSystem`, which wraps the Node.js `fs` wrapper to add resilience + caching.
// Typical usage will consume the `NodeJsInputFileSystem` + `CachedInputFileSystem`, which wraps
// the Node.js `fs` wrapper to add resilience + caching.
const fileSystem = new CachedInputFileSystem(new NodeJsInputFileSystem(), 4000);

///////////////////////////////////////////////////////////////////////////////
Expand All @@ -235,15 +165,15 @@ function makeResolveRequest(resolveCtx) {
// We wrap in try-catch otherwise errors are silent.
try {
return doResolve();
} catch (err) {
} catch (error) {
// This will log syntax errors, etc. that we make in the resolver.
console.log({ err });
console.log({ err: error });
}

function doResolve() {
if (!resolver) {
// Only create one resolver.
// TODO(vjpr): Not sure if each request needs its own resolver (because of extensions)
// Only create one resolver. TODO(vjpr): Not sure if each request needs its own resolver
// (because of extensions)

const extensions = getExtensions(context, platform);

Expand All @@ -270,21 +200,27 @@ function makeResolveRequest(resolveCtx) {
let filePath;

if (useResolveFrom) {
// `resolve-from` can be much faster than webpack, but won't work for complicated requests (e.g. exts).
// See https://github.com/webpack/enhanced-resolve/issues/110#issue-245546672
let result = resolveFrom.silent(lookupStartPath, request);
if (result) return { type: 'sourceFile', filePath: result };
// `resolve-from` can be much faster than webpack, but won't work for complicated requests
// (e.g. exts). See https://github.com/webpack/enhanced-resolve/issues/110#issue-245546672
const result = resolveFrom.silent(lookupStartPath, request);

if (result) {
return { type: 'sourceFile', filePath: result };
}
}

try {
filePath = resolver.resolveSync({}, lookupStartPath, request, resolveContext);
} catch (err) {
//console.log({err})
//console.log(JSON.stringify(err, null, 2))
console.log(err);
} catch (error) {
//console.log({err}) console.log(JSON.stringify(err, null, 2))
console.log(error);
const assets = tryAssetFile(context, request, platform);
if (assets) return assets;
throw err;

if (assets) {
return assets;
}

throw error;
}

return { type: 'sourceFile', filePath };
Expand All @@ -298,12 +234,14 @@ function tryAssetFile(context, request, platform, err) {
const dirname = path.dirname(request);
const basename = path.basename(request);
const assetResolutions = context.resolveAsset(dirname, basename, platform);

if (assetResolutions) {
return {
type: 'assetFiles',
filePaths: assetResolutions.map((name) => `${dirname}/${name}`),
};
}

return null;
}

Expand All @@ -313,12 +251,14 @@ function tryAssetFile(context, request, platform, err) {
function getExtensions(context, platform) {
const baseExtensions = context.sourceExts.map((extension) => `.${extension}`);
let finalExtensions = [...baseExtensions];

if (context.preferNativePlatform) {
finalExtensions = [
...baseExtensions.map((extension) => `.native${extension}`),
...finalExtensions,
];
}

if (platform) {
// We must keep a const reference to make Flow happy
const p = platform;
Expand All @@ -330,3 +270,5 @@ function getExtensions(context, platform) {

return finalExtensions;
}

module.exports = getConfig();
13 changes: 7 additions & 6 deletions examples/with-react-native/package.json
Expand Up @@ -6,10 +6,10 @@
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"start": "react-native start",
"test": "jest"
"start": "react-native start"
},
"dependencies": {
"@remirror/core-helpers": "1.0.0-next.60",
"@remirror/react": "1.0.0-next.60",
"@remirror/react-native": "0.0.0",
"@types/react": "^17.0.0",
Expand All @@ -30,10 +30,11 @@
"find-up": "^5.0.0",
"hermes-engine": "^0.7.2",
"jsc-android": "^241213.1.0",
"left-pad": "^1.3.0",
"metro-cache": "^0.64.0",
"metro-core": "^0.64.0",
"metro-react-native-babel-preset": "^0.64.0",
"metro": "^0.58.0",
"metro-cache": "^0.58.0",
"metro-config": "^0.58.0",
"metro-core": "^0.58.0",
"metro-react-native-babel-preset": "^0.58.0",
"metro-symlinked-deps": "^2.0.0",
"resolve-from": "^5.0.0"
},
Expand Down

0 comments on commit eed8b71

Please sign in to comment.