From 867fccf7b4b62b143cbc8e95b398ff197f0c8ae2 Mon Sep 17 00:00:00 2001 From: AIDevMonster Date: Thu, 3 Nov 2016 15:36:53 +0100 Subject: [PATCH] feat(docs): Extracting packages into their own modules (#979) * fix(internals): Fix babel relative preset Fix webpack issue with relative babel preset paths: https://github.com/babel/babel-loader/issues/149 * feat(docs): Add docs for extracting components Add draft version of docs describing how to extract components to their own npm packages. --- docs/README.md | 1 + docs/general/components.md | 107 +++++++++++++++++++++++++ internals/webpack/webpack.dev.babel.js | 6 +- 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 docs/general/components.md diff --git a/docs/README.md b/docs/README.md index 1aae2cc..ef8f217 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,6 +10,7 @@ - [FAQ](general/faq.md) - [Gotchas](general/gotchas.md) - [Remove](general/remove.md) + - [Extracting components](general/components.md) - [Testing](testing) - [Unit Testing](testing/unit-testing.md) - [Component Testing](testing/component-testing.md) diff --git a/docs/general/components.md b/docs/general/components.md new file mode 100644 index 0000000..0dd0c75 --- /dev/null +++ b/docs/general/components.md @@ -0,0 +1,107 @@ +# Extracting components + +One of the most compelling arguments for the self-contained components +architecture is the ability to easily reuse each component in other projects. +Since all the files kept in the same folder, this should be a breeze. + +## When? + +Often when working on a project, you find you've created a component that you +could use is other upcoming projects. You would like to extract that +component to its own git repository and npm package since keeping the version +histories separate makes a lot of sense. + +You're not finished with the component, but would like to continue working on it +in parallel alongside your main project. + +## How? + +Since all the files are kept in the same place, its simply a matter of moving +the folder to its own directory, setting up the `package.json` for your new +package, and including it in your main project. + +### Npm + +Npm has a great feature that allows this kind of parallel development of +packages - `npm link` (read more [here](https://docs.npmjs.com/cli/link)). After +setting up your new package, you can link it into your main package like this: + + 1. `cd` into your new package directory + 2. Run `npm link` + 3. `cd` into your main project directory + 4. Run `npm link ` + +### Configuration + +#### Specifying dependencies + +Linking the packages won't save the package as a dependency in your main project +`package.json`, so you'll have to do that manually. + +```json +"dependencies": { + "": "*", +} +``` + +#### Excluding from Dll + +This boilerplate uses the webpack DllPlugin which optimizes build times during +development. This assumes that your dependencies rarely change and precompiles +them into one big bundle. But since you will be changing your new package quite +often, this is probably not what you want. + +You can specify that you don't want this package to be included in the dll by +adding the following to your `package.json`. + +```json +"dllPlugin": { + "exclude": [ + "", + ] +} +``` + +That's it, you should be all set to work on both your packages. Webpack will +monitor both your new package and your main project for changes and rebuild +whenever you change something. This makes development a lot simpler when trying +to keep things separate while still working on them at the same time. + +## Gotchas + +As well as this approach works for development, there are some things you need +to watch out for when building and publishing your new package or project. + +### Publishing to npm registry + +In your new package, you will most likely have a build task to transpile from +ES6 into ES5. You probably keep your ES6 code in a `src/` directory and your +transpiled code in a `lib/` directory. + +In your `package.json`, you probably have something like this: + +```json + "main": "lib/index.js" +``` + +This is what you want when you publish to the registry, but during development +you probably want to change this to + +```json + "main": "src/index.js" +``` + +This will make sure that your main project always includes your most recent +code. You've just got to remember to change it back to `lib/` before publishing +to the npm registry. + +You can, of course, go down the `lib/` path, but that requires you to +rebuild your package and transpile it to ES5 whenever you introduce a change, +which can be a pain. + +### Building + +Building the package can be a little bit tricky due to how webpack handles +symlinks. We've found it easiest to remove the symlink and replace it with the +actual files, either by copying the package to `node_modules` or running +`npm install` if you've published your package to the npm registry. diff --git a/internals/webpack/webpack.dev.babel.js b/internals/webpack/webpack.dev.babel.js index 2b28a42..f4f1744 100644 --- a/internals/webpack/webpack.dev.babel.js +++ b/internals/webpack/webpack.dev.babel.js @@ -39,7 +39,11 @@ module.exports = require('./webpack.base.babel')({ // Tell babel that we want to hot-reload babelQuery: { - presets: ['react-hmre'], + // require.resolve solves the issue of relative presets when dealing with + // locally linked packages. This is an issue with babel and webpack. + // See https://github.com/babel/babel-loader/issues/149 and + // https://github.com/webpack/webpack/issues/1866 + presets: ['babel-preset-react-hmre'].map(require.resolve), }, // Emit a source map for easier debugging