filipedeschamps / rss-feed-emitter

Super RSS News Feed aggregator written in Node.js and ES6
MIT License
1.06k stars 77 forks source link

15. Build and Pre Publish scripts #135

Closed filipedeschamps closed 8 years ago

filipedeschamps commented 8 years ago

When you use a module from npm, you don't know exactly in which language the source code is made of, since it could be coded in CoffeeScript, ES6, TypeScript, etc. but you can directly require it in your Node.js script without the need to manually transpile. This is very simple to do in our module.

Build script

We already have everything we need to make a build of our source code from ES6 to ES5, you just need to add this new script to your package.json

"build": "babel src --out-dir dist"

So, every time we run this in our command line...

$ npm run build

... Babel will read all files in the src directory, transpile them to ES5 code and put them in the dist folder:

> babel src --out-dir dist

src/rss-feed-emitter.js -> dist/rss-feed-emitter.js

Ignoring files

It's a good idea to insert the dist folder inside your .gitignore file since it's not a good practice to keep them in your repository, just like node_modules. The distribution files will always have modifications and they just doesn't make sense to a source control.

So, if we aren't going to keep them in our git repository, how the end developer will access them in their application? Two very important things: .npmignore and prepublish script.

In the same way the dist folder is not important to our git repository, the src folder is not important to the developer that's using your module. If you ignore the dist folder in your .gitignore you must create a .npmignore file, otherwise npm will just ignore the dist content and the end user will not have access to those files.

So, create a .npmignore and add the src folder in it. This file is just like a normal .gitignore file and you can add other files that make no sense to the end developer, for example:

src
.travis.yml
.codeclimate.yml
.editorconfig
.eslintignore
.eslintrc
test

Prepublish script

The prepublish script is very important if you wan't to distribute your package:

If you need to perform operations on your package before it is used, in a way that is not dependent on the operating system or architecture of the target system, use a prepublish script. @ npm documentation

You can make a lot of operations with your prepublish script, but in our case, we're going just use it to build our source code into ES5, so add this to your package.json scripts:

"prepublish": "npm run build"

Main script

But hey, when someone requires our module in their scripts, how the system will now that it need to load dist/rss-feed-emitter.js (ES5) instead of src/rss-feed-emitter.js (ES6) code? It's easy and you can specify the main entry point of your script.

Open your package.json file and edit the "main" property. Probably this property has the index.js value. Change it to your distribution file:

"main": "dist/rss-feed-emitter.js"

Now, all ES5 environments will read the correct file. But there's one more thing to cover the difference between require and import.

Require vs Import

Babel 6.x changed the default behavior of how your module is exported if you're using the export default inside your ES6 module. With this, when you require your module, you need to specify the default key, for example:

var RssFeedEmitter = require('rss-feed-emitter').default

Instead of just:

var RssFeedEmitter = require('rss-feed-emitter')

We can change this behavior with a little Babel plugin called babel-plugin-add-module-exports. First, install it:

npm install babel-plugin-add-module-exports --save-dev

Then edit your .babelrc file and declare it as a plugin:

{
  "presets": ["es2015"],
  "plugins": ["babel-plugin-add-module-exports"]
}

Great, now this plugin will analyze your code and add a module.exports = exports['default']; in the end of the transpiled version.

Next step

16. Create a release tag, merge into master and publish to npm and Github