react-famous icon indicating copy to clipboard operation
react-famous copied to clipboard

Make package.js as tool-agnostic as possible

Open trusktr opened this issue 9 years ago • 13 comments

I'm gonna send a PR. The general idea is that the package.json should be agnostic of which tool the user uses. For example, see this package.json file. It is as minimal as possible and aims to support browserify, jspm, webpack. We could even add a description for RequireJS usage, but I think RequireJS is reaching the end of it's days.

That package.json is slightly outdated (using 6to5 instead of babel, old famous, etc) but we can get an idea from it. Basically, the only dependencies are

  "dependencies": {
    "army-knife": "^0.2.1",
    "famous": "git+https://github.com/trusktr/famous.git#trusktr",
    "famousify": "^0.1.5",
    "jss": "^0.10.1"
  }

The only tool specific dependency listed there is famousify which was needed for browserify, due to the way browserify works we have no option but to place that in dependencies. As for Webpack, we can list the steps needed for the developer to configure Webpack instead of including all the dependencies/loaders in package.json. For example, this README describes how to get up and running with each tooling environment.

trusktr avatar Jul 27 '15 19:07 trusktr

Another good reason to remove all the webpack stuff, and instead document it, is because all those dependencies add platform-specific build processes that might be unnecessary if the end user isn't using Webpack.

I'm getting it running in my Meteor setup using my rocket:module package for Meteor (which behind the scenes uses Webpack). I'll make some PRs when ready. :smiley:

trusktr avatar Jul 27 '15 23:07 trusktr

What we can do next is make a react-famous-webpack repo showing how to use react with Webpack, react-famous-browserify, react-famous-jspm, etc.

trusktr avatar Jul 28 '15 18:07 trusktr

@trusktr The way react-famous was structured in a similar way react-bootstrap.

webpack is only used for library development and what really gets published to NPM registry is the transpiled CommonJS code that is bundler agnostic. I run gulp build-cjs then publish the dist/cjs/. So package.json at the root of this repo is for internal use, and dist/cjs/package.json is the real one NPM uses which is already 100% tool-agnostic.

For your rocket:module integration with react-famous I'd like to suggest working with NPM published files instead of working with this repo directly. The reason this approach is better is because published files do not require an extra tool dependency at all. For user's perspective it is just a ES5 library. (most wouldn't know it was written in ES6 anyways)

pilwon avatar Jul 29 '15 06:07 pilwon

Sounds good. So it seems like one of the first things we need to do is move a bunch of the dependencies that you use for development into the devDependencies field of package.json, otherwise those dependencies are installed for anyone who will use you library when they npm install inside their own project. devDependencies are only installed when you are inside the react-famous folder and running npm install, otherwise, when react-famous is installed as a dependency in another project, the devDependencies won't be installed, saving the user a time and space. I've gotta work now through Friday. I'll have more time this weekend to start making some PRs to help organize all the development stuff. The dependencies property of package.json should basically look like this:

  "dependencies": {
    "famous": "^0.6.0",
    "lodash": "^3.4.0",
    "react": "^0.13.1"
  }

and basically everything else will go in devDependencies (I may have missed something, just rough guess right now). The stuff in dependencies are basically the things that are needed during runtime on the user's side.

trusktr avatar Jul 29 '15 19:07 trusktr

peerDependencies is deprecated now (https://github.com/pilwon/react-famous/blob/master/tools/publish/cjs/package.json#L21) so that's basically the dependencies.

trusktr avatar Jul 29 '15 19:07 trusktr

I see you had separated the publish package.json into it's separate folder in tools/publish/cjs. An alternative would be to just put prepublish scripts in a single package.json, the devDependencies in the same package.json, and all source in src like you already do, then the prepublish script build into the root of the filesystem from the source folder. What I've found is that it's nice to also publish the src folder, because some people like Webpack and JSPM users can use the original source files instead of the built files, and they can specify their own build configs for handling those files, so the publish structure could look like this:

index.js // built
foo.js // built
bar.js // built
src/
  index.js // original
  foo.js // original
  bar.js // original

trusktr avatar Jul 29 '15 19:07 trusktr

JSPM and Webpack users, can then have more flexibility to choose how to process ES6 files, for example. JSPM users can specify that src is the project root, and when JSPM installs the package, it prunes all the other files, converting the src files into the root files.

I think the best practice for a cross-build-system structure would be like I've done in infamous, with a single package.json at the root. It might not look as clean inside, but it's build-system agnostic (i.e. tries to accommodate the most build systems in the smallest way possible).

trusktr avatar Jul 29 '15 19:07 trusktr

You'll notice in the infamous package.json the prepublish script that build CommonJS for publishing to npm. I also included the build-* scripts in case anyone else wants a different format. In the README I've set instructions for JSPM, Browserify, and Webpack.

trusktr avatar Jul 29 '15 19:07 trusktr

Another advantage of having the root of the github repo be the root of the react-famous package is that when people want to install your package from git, using npm, then it'll work. It's not possible to specify sub-folders with npm, so when they install react-famous from git, it will install all those dev-dependencies that you have, and they'll have the original sources in the src folder.

trusktr avatar Jul 29 '15 19:07 trusktr

Another thing you could do, if you want to keep a higher-level folder for react-famous, for development, would be to create a separate repo, react-famous-dev, then you can import react-famous as a sub-module. You can also make a folder on your filesystem and just use npm link to test live changes to the package (that's the technique I use).

trusktr avatar Jul 29 '15 19:07 trusktr

Well, anyways, this weekend or after I'll propose a format to make the package as consumable as possible, via bower, npm, jspm, with webpack, browserify, jspm, etc.

If you could make a new repo, react-famous-example, that'd be great. We'll move the examples there and use react-famous as a dependency there.

trusktr avatar Jul 29 '15 20:07 trusktr

:+1:

On mixed-mode I hope :)

paynecodes avatar Jul 29 '15 20:07 paynecodes

@jpdesigndev Yep, I'm working on the mixed-mode branch in my fork. PRs soon. :)

trusktr avatar Jul 29 '15 20:07 trusktr