Skip to content

Commit

Permalink
feat(docs): Extracting packages into their own modules (#979)
Browse files Browse the repository at this point in the history
* fix(internals): Fix babel relative preset

Fix webpack issue with relative babel preset paths:
babel/babel-loader#149

* feat(docs): Add docs for extracting components

Add draft version of docs describing how to extract components to their own
npm packages.
  • Loading branch information
pavlin-policar authored and M-Killer-dev committed Nov 3, 2016
1 parent 00a0fa8 commit 7c12cee
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
107 changes: 107 additions & 0 deletions docs/general/components.md
Original file line number Diff line number Diff line change
@@ -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 <new-package>`

### 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": {
"<new-package>": "*",
}
```

#### 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": [
"<new-package>",
]
}
```

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.
6 changes: 5 additions & 1 deletion internals/webpack/webpack.dev.babel.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 7c12cee

Please sign in to comment.