npm i builder-js-package --save-dev
Short version: Write source code and don't worry about how make it work everywhere.
Long version: A Builder archetype (i.e. shared project structure, shared build configuration, and shared tasks and procedures) for making, building, and publishing JS-only packages in a way that makes them:
- compatible in many different build systems and environments (f.e. Webpack, Rollup, Babel, Meteor, RequireJS, globals, Node.js)
- consumable in with different module formats like AMD, UMD, CommonJS, and ES Modules
- publishable to different registries like NPM, Bower, and JSPM
Example projects using this Builder archetype are:
Notice in those projects that they have no dependencies on any build tools and no build configurations, and that they reference only this shared Builder archetype.
I'd like to make this easy to extend and even more generic to fit any needs, so that only few modifications are needed in order to adopt its use for more specific cases (f.e. adding babel plugins or webpack loaders and configs). See TODO.
- Node v9+ (might work with lower versions, not tested)
- NPM v5+ (might work with lower versions, not tested)
- If you don't have a graphical display (f.e. in Linux without a desktop) install xvfb - see https://github.com/electron/electron/blob/v1.4.10/docs/tutorial/testing-on-headless-ci.md
(Note! This part is TODO, but shared configs and procedures work. For now, see the above example projects, which all share a similar structure, to get an idea of how to structure a project in order to use this Builder archetype)
build-init builder-js-package will create a new project with the following structure. If you have
an existing package that you'd like to use this on, then you will have to modify it to follow the
src # all source files go here as well as testjs filesindexjs # entry pointindextestjs # co-located test files... # any other files imported by entry point and associated test filestests # also scanned for testjs filesgitignore # things to ignorepackagejsonbuilderrc # required specify this builder archetype inbuilderconfigjs # optional config options
This builder archetype will output compiled
.js files from
src along with
.js.map source maps
into the root of the repo (yes, you read that correctly, you should not have any files at the top
src that are the same name as files in the root of the repo).
global.js (and source map) is also outputted, containing the global version of the lib that can
be easily loaded on a website using a script tag.
This archetype can be configured with a
builder.config.js file at the root of the project.
Options (so far):
moduleexports =// If set to `false` or an empty string, then the global build will not add a// global variable into the environment. Otherwise, the library's exports will// be assigned onto a global variable of the name defined here. Defaults to// the name of the package if omitted (minus the @scope/ part if the package// names is scoped).globalName: '...' // A string, `false`, or `undefined`// a list of node modules (by name) that should be compiled.nodeModulesToCompile:'some-package'// ...// TODO babel option
This Builder archetype uses a combination of Babel to build code. Specifically, it transpiles
for..of loops with Babel in "loose" mode, which means the result is not spec compliant, but leaner
and faster in many cases although it will not work with Iterators and Generators.
This means, in projects built with this Builder archetype, you'll have to either not iterate on
for..of directly (f.e. use
Arrays instead), or use
Array.from. For example:
const items = ...// will NOT workfor const item of itemsconsole// worksfor const item of Arrayconsoleconst pairs = ...// will NOT workfor const key value of pairsconsole// worksfor const key value of Arrayconsole
- Allow override of Babel config
- Allow override of Webpack config
- Don't commit global.js (and its map) on version changes, we can tell people to get it from unpkg, GitHub, and how to build it.
- Output both a global.js and global.min.js
- Source maps! Important! (so far exists for global.js, but not the other files)
- Important! Don't run
git stashduring version script if there's nothing to stash, otherwise it will pop a previous stash after
npm versionis done.
- A project template for generating new projects with
builder-init. Probably a Yeoman generator. (update the Project Structure section above accordingly)
- Testing (added Karma)
- Code coverage (Karma is in place, just need to hook up the tasks)
- Continuous integration
- Fix the previous caveat in a way that can build for both old and new browsers so that at
least new browsers don't have a ton of unnecessary overhead in build output. We'll probably
- Maybe we can offer a dev and production server that can automatically detect browsers and serve appropriate builds.
- Move babel plugins and transforms to a custom babel preset, so we can keep package.json dependencies clean? Other benefits?