Skip to content

Commit

Permalink
feat: external bundles (#633)
Browse files Browse the repository at this point in the history
  • Loading branch information
zamotany authored Sep 9, 2019
1 parent e183e0d commit 9f51eac
Show file tree
Hide file tree
Showing 47 changed files with 11,175 additions and 131 deletions.
10 changes: 10 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ jobs:
- attach_workspace:
at: ~/haul_node_10
- run: yarn test -i integration_tests/react_native_0_60x_multibundle

monorepo_multibundle_integration_tests:
executor: node_10
steps:
- attach_workspace:
at: ~/haul_node_10
- run: yarn test -i integration_tests/monorepo_multibundle

setup_node_latest:
executor: node_latest
Expand Down Expand Up @@ -137,6 +144,9 @@ workflows:
- rn_0_60x_multibundle_integration_tests:
requires:
- setup_node_10
- monorepo_multibundle_integration_tests:
requires:
- setup_node_10
- setup_node_latest
- lint_and_typecheck_node_latest:
requires:
Expand Down
87 changes: 86 additions & 1 deletion docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ The bundle configuration consist of the following properties:
- `providesModuleNodeModules?: Array<string | { name: string; directory: string }>` - Provide custom modules for Haste.
- `hasteOptions?: any` - Provide Haste options.
- `transform?: WebpackConfigTransform` - Customize the Webpack config after it's been created.
The `transform` function will receive an object with `bundleName`, `env`, `runtime` and Webpack's `config`:
```js
Expand All @@ -120,6 +120,11 @@ The bundle configuration consist of the following properties:
```

More information can be found in [Customize Webpack config recipe](#customize-webpack-config).
- `bundlePath?: string` - Absolute path to an external (pre-built) bundle.
- `manifestPath?: string` - Absolute path to manifest for an external (pre-built) bundle, if `dll` is `true`.
- `assetsPath?: string` - Absolute or relative path pointing to where assets for an external (pre-built) bundle are stored. If relative, it will be joined with `path.dirname(bundlePath)`.
- `copyBundle?: boolean` - Whether to copy bundle, source map and assets of an external (pre-built) bundle to output directory.


If you want to provide the bundle config based on received CLI arguments, you can do so, by using `BundleConfigBuilder`:

Expand Down Expand Up @@ -376,3 +381,83 @@ class RootComponent extends React.Component {
AppRegistry.registerComponent('MyApp', () => RootComponent);
```
### External (pre-built) bundles
Check out [monorepo fixture](../fixtures/monorepo) for a complete an example.
To use external bundles, first build the bundles that will be considered pre-built. You only need a single bundle config:
```js
import { withPolyfills, makeConfig } from '@haul-bundler/preset-0.60';
import { join } from 'path';
const entry = withPolyfills([
require.resolve('react'),
require.resolve('react-native'),
require.resolve('react-navigation'),
]);
export default makeConfig({
bundles: {
base_dll: ({ dev }) => ({
entry,
dll: true,
// Packager server will use development bundle, so it should be built as a plain JS bundle.
type: dev ? 'basic-bundle' : 'indexed-ram-bundle',
}),
},
});
```
Use `--skip-host-check` option when building pre-built bundles:
```sh
yarn haul multi-bundle --skip-host-check <...>
```
Now in a project, where you want to use pre-built bundles, you need to specify, which bundle is external one:
```js
import {makeConfig, withPolyfills} from '@haul-bundler/preset-0.59';
export default makeConfig({
bundles: {
index: {
entry: withPolyfills('./src/host.js'),
dependsOn: ['base_dll'],
},
// Let's assume base-dll bundle is a Node module.
base_dll: ({ platform, bundleTarget, dev }) => {
// For a pre-built bundle, both development and production bundle have to be present.
const basePath = join(
__dirname,
`node_modules/base-dll/dist/${platform}/${dev ? 'dev' : 'prod'}`
);
const filename = `base_dll${
platform === 'ios' ? '.jsbundle' : '.android.bundle'
}`;
return {
dll: true,
copyBundle,
bundlePath: join(basePath, filename),
manifestPath: join(basePath, 'base_dll.manifest.json'),
}
},
// Let's assume app bundle is a Node module.
app: ({ platform, dev }) => {
const basePath = join(
__dirname,
`node_modules/app/dist/${platform}/${dev ? 'dev' : 'prod'}`
);
const filename = `app0${
platform === 'ios' ? '.jsbundle' : '.android.bundle'
}`;

return {
bundlePath: join(basePath, filename),
copyBundle: true,
};
},
},
});
```

Now when building a static bundle, the other external bundles alongside it's assets and source maps will be copied to next to `index` bundle.
53 changes: 53 additions & 0 deletions fixtures/monorepo/app0/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View, TouchableOpacity } from 'react-native';

const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
android:
'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});

export default class App extends Component {
state = {
counter: 0,
}

render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>App 0</Text>
<Text style={styles.instructions}>To get started, edit App.js</Text>
<Text style={styles.instructions}>{instructions}</Text>
<Text style={styles.instructions}>Counter: {this.state.counter}</Text>
<TouchableOpacity onPress={() => {
this.setState(state => ({ counter: state.counter + 1 }))
}}><Text style={styles.instructions}>Increment</Text></TouchableOpacity>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 36,
textAlign: 'center',
color: '#282828',
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
body: {
fontSize: 24,
textAlign: 'center',
color: '#282828',
},
});
1 change: 1 addition & 0 deletions fixtures/monorepo/app0/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../babel.config');
13 changes: 13 additions & 0 deletions fixtures/monorepo/app0/haul.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { withPolyfills, makeConfig } from '../../../packages/haul-preset-0.60';
import makeBaseDllConfig from 'base-dll/makeConfig';

export default makeConfig({
bundles: {
base_dll: makeBaseDllConfig(),
app0: {
entry: './App',
dependsOn: ['base_dll'],
app: true,
}
},
});
23 changes: 23 additions & 0 deletions fixtures/monorepo/app0/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "app0",
"version": "0.1.0",
"files": [
"dist/"
],
"scripts": {
"haul": "node ../../../packages/haul-cli/bin/haul.js",
"build:base": "yarn haul multi-bundle --skip-host-check",
"build:ios:dev": "yarn build:base --platform ios --dev true --bundle-output dist/ios/dev --assets-dest dist/ios/dev",
"build:ios:prod": "yarn build:base --platform ios --dev false --bundle-output dist/ios/prod --assets-dest dist/ios/prod",
"build:android:dev": "yarn build:base --platform android --dev true --bundle-output dist/android/dev --assets-dest dist/android/dev",
"build:android:prod": "yarn build:base --platform android --dev false --bundle-output dist/android/prod --assets-dest dist/android/prod",
"build:all": "yarn build:ios:dev && yarn build:ios:prod && yarn build:android:dev && yarn build:android:prod"
},
"dependencies": {
"react": "^16.8.6",
"react-native": "^0.60.5",
"react-native-gesture-handler": "^1.3.0",
"react-navigation": "^3.11.0",
"base-dll": "*"
}
}
3 changes: 3 additions & 0 deletions fixtures/monorepo/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: [`module:${require.resolve('../../packages/haul-babel-preset-react-native')}`],
};
1 change: 1 addition & 0 deletions fixtures/monorepo/base-dll/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../babel.config');
18 changes: 18 additions & 0 deletions fixtures/monorepo/base-dll/haul.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { withPolyfills, makeConfig } from '../../../packages/haul-preset-0.60';
import { join } from 'path';

const entry = withPolyfills([
require.resolve('react'),
require.resolve('react-native'),
require.resolve('react-navigation'),
]);

export default makeConfig({
bundles: {
base_dll: ({ dev }) => ({
entry,
dll: true,
type: dev ? 'basic-bundle' : 'indexed-ram-bundle',
}),
},
});
19 changes: 19 additions & 0 deletions fixtures/monorepo/base-dll/makeConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { join } from 'path';

export default function makeConfig(copyBundle = false) {
return ({ platform, bundleTarget, dev }) => {
const basePath = join(
__dirname,
`./dist/${platform}/${dev || bundleTarget === 'server' ? 'dev' : 'prod'}`
);
const filename = `base_dll${
platform === 'ios' ? '.jsbundle' : '.android.bundle'
}`;
return {
dll: true,
copyBundle,
bundlePath: join(basePath, filename),
manifestPath: join(basePath, 'base_dll.manifest.json'),
}
};
}
23 changes: 23 additions & 0 deletions fixtures/monorepo/base-dll/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "base-dll",
"version": "0.1.0",
"files": [
"makeConfig.js",
"dist/"
],
"scripts": {
"haul": "node ../../../packages/haul-cli/bin/haul.js",
"build:base": "yarn haul multi-bundle --skip-host-check",
"build:ios:dev": "yarn build:base --platform ios --dev true --bundle-output dist/ios/dev --assets-dest dist/ios/dev",
"build:ios:prod": "yarn build:base --platform ios --dev false --bundle-output dist/ios/prod --assets-dest dist/ios/prod",
"build:android:dev": "yarn build:base --platform android --dev true --bundle-output dist/android/dev --assets-dest dist/android/dev",
"build:android:prod": "yarn build:base --platform android --dev false --bundle-output dist/android/prod --assets-dest dist/android/prod",
"build:all": "yarn build:ios:dev && yarn build:ios:prod && yarn build:android:dev && yarn build:android:prod"
},
"dependencies": {
"react": "^16.8.6",
"react-native": "^0.60.5",
"react-native-gesture-handler": "^1.3.0",
"react-navigation": "^3.11.0"
}
}
Loading

0 comments on commit 9f51eac

Please sign in to comment.