Skip to content

Instantly share code, notes, and snippets.

@EmielM
Created July 27, 2017 12:48
Show Gist options
  • Save EmielM/0d59a0c4e711ace245ab736f208fc6be to your computer and use it in GitHub Desktop.
Save EmielM/0d59a0c4e711ace245ab736f208fc6be to your computer and use it in GitHub Desktop.
react-native rollup bundle attempt
import fs from 'fs';
import path from 'path';
import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import nodeResolve from 'rollup-plugin-node-resolve';
import typescript from 'rollup-plugin-typescript';
import replace from 'rollup-plugin-replace';
function findVersion(file, extensions) {
for (let e of extensions) {
if (fs.existsSync(file+e)) {
console.log("found version", file+e);
return file+e;
}
}
return null;
}
function hasteResolve(opts) {
const hasteMap = {};
const walk = function(file) {
const stat = fs.statSync(file);
if (stat.isDirectory()) {
fs.readdirSync(file).forEach(function(file0) {
if (file0.indexOf([
// blacklist
'node_modules', '__tests__', '__mocks__',
'__fixtures__', 'react-packager', 'androidTest'
]) >= 0) {
return;
}
walk(file+'/'+file0);
});
return;
}
if (stat.isFile()) {
let fileName = (/^(.*)\.js$/.exec(file) || [])[1];
if (!fileName) {
return;
}
const m = /^(.*)\.(\w+)$/.exec(fileName);
if (m && ['ios', 'android', 'native', 'web'].indexOf(m[2]) >= 0) {
fileName = m[1];
}
const content = fs.readFileSync(file, 'utf-8');
const moduleName = (/\* @providesModule ([\w.-]+)/.exec(content)||[])[1];
if (!moduleName) {
return;
}
if (hasteMap[moduleName] && hasteMap[moduleName] !== fileName) {
throw new Error('Duplicate haste module: '+moduleName+' in files: '+fileName+' & '+hasteMap[moduleName]);
}
hasteMap[moduleName] = fileName;
}
};
const dir = opts.include.replace(/\/\*\*$/, '');
walk(dir);
return {
name: 'haste-resolve',
resolveId(importee, importer) {
if (hasteMap[importee]) {
return findVersion( path.resolve(hasteMap[importee]), opts.extensions || ['.js'] );
}
return null;
}
};
}
export default {
entry: 'app/test.tsx',
dest: 'build/app.js',
format: 'iife',
plugins: [
typescript({
typescript: require('typescript'),
}),
hasteResolve({
include: 'node_modules/react-native/**',
extensions: ['.ios.js', '.native.js', '.js']
}),
nodeResolve({
include: ['node_modules/react-native/**', 'node_modules/react/**'],
//exclude: 'node_modules/react-native/**',
jsnext: true,
extensions: ['.ios.js', '.native.js', '.js']
}),
babel({
//exclude: 'node_modules/**',
include: [
'node_modules/react-native/**',
'node_modules/react-clone-referenced-element/**'
],
babelrc: false,
plugins: [
'syntax-async-functions',
'syntax-class-properties',
'syntax-trailing-function-commas',
'transform-class-properties',
'transform-es2015-function-name',
'transform-es2015-arrow-functions',
'transform-es2015-block-scoping',
'transform-es2015-classes',
'transform-es2015-computed-properties',
'check-es2015-constants',
'transform-es2015-destructuring',
'transform-es2015-parameters',
'transform-es2015-shorthand-properties',
'transform-es2015-spread',
'transform-es2015-template-literals',
'transform-es2015-literals',
'transform-flow-strip-types',
'transform-object-assign',
'transform-object-rest-spread',
'transform-react-display-name',
'transform-react-jsx',
'transform-regenerator',
['transform-es2015-for-of', { loose: true }],
'external-helpers'
]
}),
replace({
//'\\bprocess.env.NODE_ENV': '"production"',
'__DEV__': 'false',
}),
commonjs({
include: [
'node_modules/react-native/**', 'node_modules/react/**',
'node_modules/fbjs/**', 'node_modules/pretty-format/**',
'node_modules/event-target-shim/**', 'node_modules/stacktrace-parser/**',
'node_modules/react-clone-referenced-element/**', 'node_modules/promise/**'
],
namedExports: {
'node_modules/react/react.js': ['createElement'],
'node_modules/react-native/Libraries/react-native/react-native-implementation.js': ['View', 'Text', 'AppRegistry']
}
}),
{
ongenerate(opts) {
const {modules} = opts.bundle;
const deps = {};
modules.forEach( (m) => {
deps[m.id] = {}; // = m.dependencies;
m.dependencies.forEach( (d) => {
deps[m.id][d] = true;
});
});
const cycles = {};
const walk = (path) => {
Object.keys(deps[path[0]]||{}).forEach( (id) => {
const path0 = [id].concat(path);
const f = path0.slice(1).indexOf(id)
if (id[0] != '\0' && f >= 0) {
if (!cycles[id]) {
console.log("cycle: ", path0.slice(0,f+2).reverse().map( (x) => x.replace(/^.*node_modules\//, '') ).join(' -> '));
}
cycles[id] = true;
return;
}
walk(path0);
});
deps[path[0]] = [];
};
for (let k in deps) {
walk([k])
}
}
}
]
};
@danielgindi
Copy link

There's a PR by me, that works for me in production environments to handle cyclic dependencies:
rollup/rollup-plugin-commonjs#331

The failed tests are for edge ES6 cases - where the tests themselves are not that good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment