neutrinojs / neutrino

Create and build modern JavaScript projects with zero initial configuration.
https://neutrinojs.org
Mozilla Public License 2.0
3.95k stars 213 forks source link

feat: support Preset #1653

Closed xiaoxiaojx closed 3 years ago

xiaoxiaojx commented 3 years ago

hi,

I'm the user of neutrino, We have a lot of projects with different configurations and dependencies, and I would like to add this change so that different projects can publish their own presets for better reuse.

If you think it's feasible, I can add to the test cases.

Thanks 😄 ~

@eliperelman @edmorley

constgen commented 3 years ago

Reading source code does not explicitly explains what is this change for. Can you add some use cases or description of new API?

xiaoxiaojx commented 3 years ago

Reading source code does not explicitly explains what is this change for. Can you add some use cases or description of new API?


Project configuration for an average developer

// .neutrinorc.js
{
 extends: 'my-company-react-app-preset'
}

About my-company-react-app preset

{
 extends: 'my-company-web-app-preset',
 use: ['babel-react-app-middleware', 'react-refresh-middleware']
}

...

What I want is for them to derive react-app, vue-app, electron-app, umd ... based on a basic preset. And different business units may have different customization logic based on the advanced preset, and then give every developer a preset that can be used with zero configuration.

Ability to break up currently nested middleware into a single, flattened, and combined preset with a certain number of single middleware.

👀

constgen commented 3 years ago

You can easily configure the same thing with an existing API. Your examples may look like this

// .neutrinorc.js
let myCompanyReactPreset = require('my-company-react-app-preset')

module.exports = {
 use: [ myCompanyReactPreset() ]
}
// my-company-react-app-preset

let babel= require('babel-react-app-middleware')
let reactRefresh = require('react-refresh-middleware')

module.exports = function(){
  return function(neutrino){
    neutrino.use(babel())
    neutrino.use(reactRefresh())
  }
}

Tell me if I am not right. You can find more examples in the source code of this branded organization React Preset https://github.com/atomspace/atomspace-react that reuses the similar middlewares as in in your case

xiaoxiaojx commented 3 years ago

You can easily configure the same thing with an existing API. Your examples may look like this

// .neutrinorc.js
let myCompanyReactPreset = require('my-company-react-app-preset')

module.exports = {
 use: [ myCompanyReactPreset() ]
}
// my-company-react-app-preset

let babel= require('babel-react-app-middleware')
let reactRefresh = require('react-refresh-middleware')

module.exports = function(){
  return function(neutrino){
    neutrino.use(babel())
    neutrino.use(reactRefresh())
  }
}

Tell me if I am not right. You can find more examples in the source code of this branded organization React Preset https://github.com/atomspace/atomspace-react that reuses the similar middlewares as in in your case


xiaoxiaojx commented 3 years ago

Yes, there is no problem to write it this way. The first version I implemented it like this according to the documentation Then it was more middleware and I didn't want to write neutrino.use(xxx-middleware) repeatedly all the time, so I started to wrap it simply

const middlewares = [
  require.resolve('./prerender'),
  require.resolve('./es-check'),
  require.resolve('./module-aliases'),
  require.resolve('./analyze'),
  require.resolve('./env-define'),
  require.resolve('./rocket'),
  require.resolve('./override-webpack-config'),
 ...
]

/**
 * @type NeutrinoMiddleware
 */
module.exports = require('some-util').generate(middlewares)

module.exports.middlewares = middlewares

Maybe I just want to put the generate functions into the framework, so that I can export a simple object that will be loaded and applied correctly

I also want a middleware to do only one thing

constgen commented 3 years ago

You still may want to call neutrino.use() multiple times as every middleware has its own configuration. If you want to apply multiple middlewares in a single line just compose midlewares into a single middleware or preset. This already is designed to work.

I still think that you are going to add an extra way to do the same think that already works. Can you share the link with the real usage? May be you just need a little help. May be it is not so complex as you think

xiaoxiaojx commented 3 years ago

You still may want to call neutrino.use() multiple times as every middleware has its own configuration.


For this my current implementation is similar to the one read from neutrino.options, For example, the prerender middleware will read neutrino.options.prerender, and the es-check middleware will read neutrino.options.esCheck. I want each addition of a neutrino. options is the result of applying one of the middleware

My change is just to chain the dependent presets and get the aggregated middleware and merged options, because each preset may have different default options, and the advanced preset's options will override the base preset

Sorry, I can't provide the actual code link, it's an internal company project

constgen commented 3 years ago

What you described is completely supported in the current implementation. I don't see any issue with this that we have to resolve. Are you sure that we need some changes in the core?

edmorley commented 3 years ago

Hi! Thank you for the PR. However:

  1. It's not 100% clear what the use-case is here (in general when adding new features to an open source project, I would recommend (a) first opening an issue rather than a PR, or (b) making sure the PR description explains exactly what the changes are for in lots of detail).
  2. From reading between the lines, it sounds like much of the use-case is already possible without this change
  3. Neutrino is currently not actively maintained, since there are few people who help with development, and the original maintainers no longer use the project (in my case, I'm not working on frontend projects at the moment).

I'm closing this PR for now but happy for you to open a GitHub issue to discuss the feature request in more detail. (A PR is a bit premature at the moment.)

xiaoxiaojx commented 3 years ago

Thank you for your reply, I haven't been paying attention for a while, so let's keep the status quo for now

xiaoxiaojx commented 3 years ago

hi @edmorley @constgen I put this idea into this repository ( https://github.com/ezrealjs/ezreal ), because I've been using neutrino for a year in my team's cli development, and I agree with neutrino's middleware chaining idea of building webpackConfig, so I've just optimized it for user habits