Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building npm module #84

Closed
heygrady opened this issue Mar 1, 2017 · 10 comments
Closed

Building npm module #84

heygrady opened this issue Mar 1, 2017 · 10 comments
Assignees
Labels
Milestone

Comments

@heygrady
Copy link

@heygrady heygrady commented Mar 1, 2017

I want to use Neutrino to create NPM modules. I had figured I could use neutrino-preset-node for this. I'm having some trouble getting it working.

  1. Create a new project, following the manual.
  2. Build the project with yarn build (I added the build script mentioned in the manual)
  3. Notice that the build folder contains an index.js

That's all well and good but it doesn't seem quite right.

Issues

  • The first line of build/index.js looks like it references my local computer. That's no good if I want to deploy my module to NPM.

    require('/a/path/on/my/laptop/my-neutrino-based-npm-module/node_modules/source-map-support/source-map-support.js').install();
  • When I link my module — using npm link — and link it into a local project — using npm link my-neutrino-based-npm-module — I get webpack errors. I'm importing my module into a react-redux-starter-kit project.

    import something from 'my-neutrino-based-npm-module'

    This is the error I get

    ERROR in /a/path/on/my/laptop/my-neutrino-based-npm-module/build/index.js
    Module build failed: ReferenceError: Unknown plugin "transform-runtime" specified in "base" at 0, attempted to resolve relative to "/a/path/on/my/laptop/my-neutrino-based-npm-module/build"
      at /a/path/on/my/laptop/react-redux-starter-kit-example/node_modules/babel-core/lib/transformation/file/options/option-manager.js:180:17
      at Array.map (native)
      at Function.normalisePlugins (/a/path/on/my/laptop/react-redux-starter-kit-example/node_modules/babel-core/lib/transformation/file/options/option-manager.js:158:20)
      at OptionManager.mergeOptions (/a/path/on/my/laptop/react-redux-starter-kit-example/node_modules/babel-core/lib/transformation/file/options/option-manager.js:234:36)
      at OptionManager.init (/a/path/on/my/laptop/react-redux-starter-kit-example/node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
      at File.initOptions (/a/path/on/my/laptop/react-redux-starter-kit-example/node_modules/babel-core/lib/transformation/file/index.js:216:65)
      at new File (/a/path/on/my/laptop/react-redux-starter-kit-example/node_modules/babel-core/lib/transformation/file/index.js:139:24)
      at Pipeline.transform (/a/path/on/my/laptop/react-redux-starter-kit-example/node_modules/babel-core/lib/transformation/pipeline.js:46:16)
      at transpile (/a/path/on/my/laptop/react-redux-starter-kit-example/node_modules/babel-loader/lib/index.js:46:20)
      at /a/path/on/my/laptop/react-redux-starter-kit-example/node_modules/babel-loader/lib/fs-cache.js:79:18
          at ReadFileContext.callback (/a/path/on/my/laptop/react-redux-starter-kit-example/node_modules/babel-loader/lib/fs-cache.js:15:14)
          at FSReqWrap.readFileAfterOpen [as oncomplete] (fs.js:365:13)
       @ ./src/routes/Home/components/HomeView.js 11:24-53
    
@eliperelman
Copy link
Member

@eliperelman eliperelman commented Mar 1, 2017

@heygrady can you try v4.2.2 and see if the source map error goes away?

@eliperelman eliperelman reopened this Mar 1, 2017
@heygrady
Copy link
Author

@heygrady heygrady commented Mar 1, 2017

I blew away my yarn.lock and my node_modules. I removed all depencencies from package.json and started over with yarn add.

  1. Adding the neutrino files to a package.json with no dependencies.

    yarn add --dev neutrino neutrino-preset-jest neutrino-preset-node neutrino-preset-standard
  2. Ended up with the following entries:

{
  "scripts": {
    "test": "neutrino test --presets neutrino-preset-standard neutrino-preset-node neutrino-preset-jest",
    "start": "neutrino start --presets neutrino-preset-standard neutrino-preset-node && node build/index.js",
    "build": "neutrino build --presets neutrino-preset-standard neutrino-preset-node"
  },
  "devDependencies": {
    "neutrino": "^4.3.0",
    "neutrino-preset-jest": "^4.3.0",
    "neutrino-preset-node": "^4.2.2",
    "neutrino-preset-standard": "^4.3.3"
  }
}
  1. Ran a fresh build using yarn build. No sourcemap at the top (which is good).
  2. Looked in node_modules and saw that source-map-support is in there. It must be required by a different module.
  3. There is still a build/index.js.map file generated. Not sure if this is expected.

NOTE: I saw in the docs that neutrino will read config.presets from the package.json, but that doesn't seem to work for me. The following will not work.

{
  "config": {
    "presets": [
      "neutrino-preset-standard",
      "neutrino-preset-node",
      "neutrino-preset-jest"
    ]
  },
  "scripts": {
    "test": "neutrino test",
    "start": "neutrino start && node build/index.js",
    "build": "neutrino build"
  },
  "devDependencies": {
    "neutrino": "^4.3.0",
    "neutrino-preset-jest": "^4.3.0",
    "neutrino-preset-node": "^4.2.2",
    "neutrino-preset-standard": "^4.3.3"
  }
}
@heygrady
Copy link
Author

@heygrady heygrady commented Mar 1, 2017

BTW, the sourcemap didn't seem to be the problem in my case (still getting the error "Unknown plugin 'transform-runtime'"). The real problem is that I'm trying to create a library. I'm realizing now that neutrino-preset-node doesn't really support my use case.

I was hoping that I could easily get an NPM module going, similar in nature to what you find in redux or redux-actions. Those are node packages that use babel and webpack slightly differently, to generate a lib folder with all of the transpiled ES5 code and also creating a UMD build as well.

In practical terms this would require creating a neutrino prepublish script. I think I'm going to fall-back to just copying the babel/webpack setup from redux like I've done on previous projects.

@eliperelman
Copy link
Member

@eliperelman eliperelman commented Mar 1, 2017

I'm glad some progress has been made. Yes, source maps would still be generated, just no longer included.

Regarding generating a UMD bundle, it should only take a few tweaks. And building to lib instead of build would also be similar. You wouldn't need a special prepublish command, only to create the build before publishing.

{
  "config": {
    "neutrino": {
      "output": {
        "libraryTarget": "umd",
        "library": "libName",
        "path": "lib"
      }
    }
  },
  "scripts": {
    "prepublish": "neutrino build"
  }
}

As far as the config.presets not working that sounds strange. Is there any console output when it doesn't work?

@heygrady
Copy link
Author

@heygrady heygrady commented Mar 1, 2017

WRT config.presets it builds just fine, just without any of the presets. So, if I try it with the presets in config.presets I still get the sourcemap included. If I use --presets then it doesn't include the sourcemap.

This should probably be a separate issue... I was trying to get the .eslintrc.js working and was having trouble. I kept getting an error about pkg.config.presets. Something like "cannot read key 'presets' of undefined". I figured that neutrino was somehow reading the wrong package.json — so I just hard-coded the array and it worked fine. Might be related to this issue.

The example config you supplied is only half the battle. If you look closely at what redux does when you do yarn build you can see that neutrino-presets-node isn't going to work. In my case my src folder has many files in it and I need every file to be transpiled 1-for-1 into a lib folder so that it can be used as an NPM module in other projects. Personally I don't care about UMD builds because I don't include JS in the browser directly. I just need my code to be transpiled into the lib folder.

Thanks for the note on prepublish, I had planned on doing something very similar.

I guess there's a big difference between a "node application" — which would reasonably have a single entrypoint — and a "node library" — which would allow users to import specific files at-will.

@eliperelman
Copy link
Member

@eliperelman eliperelman commented Mar 1, 2017

I'll take a look into the presets issue to see if I can replicate.

You are correct about the 1:1 compilation issue, out of the box Neutrino will only generate that index bundle. To create a bundle for each file would mean creating an entry per file you want to output to the build that does not get imported into another entry point.

@heygrady
Copy link
Author

@heygrady heygrady commented Mar 2, 2017

You can see in the redux example that they use webpack only for the UMD build. For the other outputs they use babel directly.

The relevant line from their package.json

{
  "scripts": {
    "build:commonjs": "cross-env BABEL_ENV=commonjs babel src --out-dir lib"
  }
}

It would be nice to maybe have a preset for each build target. From what I see in redux, that would be:

  • neutrino-preset-node-lib (called "build:common" in redux, 1:1 transpile into lib)
  • neutrino-preset-node-esnext (called "build:es" in redux, 1:1 transpile into es)
  • neutrino-preset-node-umd (called "build:umd" in redux, webpack UMD build into dist)
  • neutrino-preset-node-umd-min (called "build:umd:min" in redux, webpack UMD build plus minify into dist)
@eliperelman eliperelman added the feature label Mar 23, 2017
@eliperelman
Copy link
Member

@eliperelman eliperelman commented May 4, 2017

I've just experimented with creating my first React component library using a Neutrino preset:

neutrino-preset-react-components
react-lazylog

There should be some good bits there we can extract for creating generic libraries.

@eliperelman eliperelman added this to the v8 milestone Nov 1, 2017
@eliperelman
Copy link
Member

@eliperelman eliperelman commented Nov 2, 2017

Initial proof-of-concept of a library preset:

https://github.com/eliperelman/neutrino-dev/compare/scoped-packages...eliperelman:library-preset

Plan on shipping an iteration of this with Neutrino v8.

cc: @edmorley @helfi92

Once we land multiple config support, we should be able to do something like:

const name = 'example';

module.exports = [
  {
    use: [
      ['@neutrinojs/library', { name }]
    ]
  },
  {
    output: 'cjs',
    use: [
      ['@neutrinojs/library', { name, libraryTarget: 'commonjs2' }]
    ]
  }
]
@eliperelman eliperelman self-assigned this Nov 14, 2017
@eliperelman
Copy link
Member

@eliperelman eliperelman commented Nov 21, 2017

Addressed in #425.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

2 participants
You can’t perform that action at this time.