neutrino icon indicating copy to clipboard operation
neutrino copied to clipboard

Provide example for resolving module paths to source dir (FAQ?)

Open timkelty opened this issue 6 years ago • 15 comments

  • https://spectrum.chat/?t=e97230f7-2f18-4a3f-917a-fe3f391a2239
  • https://spectrum.chat/?t=ea23e41e-8751-4b15-a7ee-24340763a04a

It seems common that people want to add a module resolving path to their source path.

The easiest way to do this is:

neutrino.config.resolve.modules.add(neutrino.options.source)

Or if an alias is preferred:

neutrino.config.resolve.alias.set('@', neutrino.options.source);

timkelty avatar Mar 13 '18 12:03 timkelty

I'm actually trying to do this myself right now, and I can't get this to work:

module.exports = {
    options : {
        mains : {
            index : "index",
            index2: "index2",
        },
    },

    use : [
        [
            '@neutrinojs/react',
            (neutrino) => neutrino.config.resolve.modules.add(neutrino.options.source),
            {
                html : {
                    title : "Test App"
                }
            },
        ]
    ]
};

As best as I can tell, passing a middleware after the reactjs preset simply does not get executed. If I run with this config, I get Webpack resolution errors saying it can't find an absolute import (like import MyComponent from "common/MyComponent"). If I move the resolve middleware to be before the React one, I get Webpack validation errors telling me that Webpack has been initialised using a configuration object that does not match the API schema. configuration misses the property 'entry'.

Similarly, if I add logging and a process.exit() call to a middleware, putting it after the reactjs preset show no log output and the process continues, whereas putting it before the reactjs preset prints some log statements and kills the process.

There's gotta be something obvious here that I'm missing, but I don't know what.

markerikson avatar Mar 15 '18 03:03 markerikson

I'm already write this problem on the spectrum.chat I can achieve to resolve 'src' with configuration bellow without any problem: .neutrionorc.js

module.exports = {
  use: [
    [
      '@neutrinojs/react',
      {
        html: {
          title: 'njs-react-no-lint'
        }
      },
    ],
    (neutrino) => {      
      neutrino.config.resolve
        .modules
          .add(neutrino.options.source),
    },
  ],
};

The root 'src' is resolved, and i can use import of my components like this:

import React from 'react';

import Button from 'components/Button'; // --- resolved by webpack ---

import './App.css';

const App = () => (
  <div className="App">
    <h1>{'Neutrino with eslint configured without middleware only => .eslintrc.js'}</h1>
    <Button>Button</Button>
  </div>
);

export default App;

Real issue comming if i try to make working airbnb eslint rules with: 'eslint-plugin-import' package. I can't make it working the way 'elint-plugin-import' will stop to complain about lint error like on screenshot bellow.

lint-error

Here is my .neutrionorc.js configuration where i'm trying to resolve the issue with eslint:

const { resolve } = require('path');
const { merge } = require('@neutrinojs/compile-loader');

module.exports = {
  use: [
    [
      '@neutrinojs/react',
      {
        html: {
          title: 'njs-react-no-lint'
        }
      },
    ],

    (neutrino) => {
      
    neutrino.config.resolve
      .modules
        .add(neutrino.options.source),

    neutrino.config.module
      .rule('compile')
        .use('babel')
          .tap(options => merge({
            plugins: [
              [
                require.resolve('babel-plugin-root-import'),
                {
                  rootPathPrefix: '@',
                  rootPathSuffix: 'src',
                }
              ],
            ]
          }, options));
    },

  ],
};

I'm use babel-plugin-root-import and eslint-import-resolver-babel-plugin-root-import to make lint stop to complain about this error, but i'm also tried another adviced modules nothing is working. Lint error is still there in Atom and Terminal What is pretty anoying, but import is working.

So for now my solution is to disallow this two linting rules in my eslint configuration.

YuriiF avatar Mar 15 '18 10:03 YuriiF

@markerikson I think you have some problems with your middleware formatting (if I'm understanding correctly). Can you try it like this:

module.exports = {
    options : {
        mains : {
            index : "index",
            index2: "index2",
        },
    },
    use : [
      ['@neutrinojs/react', {
        html : {
            title : "Test App"
        }
      }],
      (neutrino) => neutrino.config.resolve.modules.add(neutrino.options.source),
    ]
};

timkelty avatar Mar 15 '18 12:03 timkelty

.....

Oh. Y'know what? I think I see what you're getting at. The array brackets may be off-by-one-ish there, so I'm accidentally putting the middleware inside the "@neutrinojs/react" array, rather than inside the "use" array. I'll try that this evening.

markerikson avatar Mar 15 '18 16:03 markerikson

@markerikson yep. I tend to find the array middleware format a little hard to read for that reason.

All preferences, but I would probably avoid it like so:

[
  (neutrino) => {
    neutrino.use('@neutrinojs/react', {
      html: {
        title: "Test App"
      }
    });
    
    neutrino.config.resolve.modules.add(neutrino.options.source);
  }
]

// or:
[
  (neutrino) => neutrino.use('@neutrinojs/react', {
    html: {
      title: "Test App"
    }
  }),
  (neutrino) => neutrino.config.resolve.modules.add(neutrino.options.source),
]

timkelty avatar Mar 15 '18 17:03 timkelty

Yeah, that was it. Boy, do I feel silly :) Thanks!

markerikson avatar Mar 16 '18 01:03 markerikson

Also I'm think my case with resolving modules for eslint is related to this issue: https://github.com/mozilla-neutrino/neutrino-dev/issues/708 Beacuas import/no-unresolved should not fail if i configured import/resolver correctly. I'm tried it with yarn eslint only and it's working without eslint errors.

This is maybe also not right place for issue in my case sorry for that, but i can suggest to write about how to configure import/resolver in to documentation, it will be great example for future users.

YuriiF avatar Mar 16 '18 09:03 YuriiF

@YuriiF I'll try and use you config to debug today.

timkelty avatar Mar 16 '18 09:03 timkelty

@timkelty Great thanks here is two gist's with neutrino configuration and package.json that i'm tried hope it will help:

https://gist.github.com/YuriiF/6c1274aa86bb3aef49b32b2a11732098 https://gist.github.com/YuriiF/83d0301123c51917de26e2f8b4215570

I'm tried two resolvers for eslint:

  • babel-plugin-root-import
  • babel-plugin-module-resolver

YuriiF avatar Mar 16 '18 12:03 YuriiF

I was having the same problem, i debugged neutrino with:

nodemon --inspect-brk ./node_modules/neutrino/bin/neutrino.js lint

Eslint somehow gets an eslint config with some of our configs overridden when neutrino sets useEslintrc: false

image

I added useEslintrc: true to my eslint config and it's working now.

yasinuslu avatar Mar 19 '18 07:03 yasinuslu

Oooo, that's a good point. I wonder if we should revise the eslintrc command to actually set useEslintrc just when calling that method?

eliperelman avatar Mar 19 '18 11:03 eliperelman

That could be problematic if the user doesn't actually have an eslintrc file. Maybe we can check and if there is an eslintrc file exists in project root, we can then set useEslintrc ? But that seems a bit hacky :)

yasinuslu avatar Mar 19 '18 13:03 yasinuslu

The eslintrc command is meant to be called from an eslintrc file, so calling the command should imply the existence of the file.

eliperelman avatar Mar 19 '18 13:03 eliperelman

That makes sense :)

yasinuslu avatar Mar 20 '18 06:03 yasinuslu

Not working on Jest:

// .neutrinorc.js
const standard = require('@neutrinojs/standardjs');
const node = require('@neutrinojs/node');
const jest = require('@neutrinojs/jest');

module.exports = {
  options: {
    root: __dirname,
    tests: 'src',
  },
  use: [
    standard(),
    node(),
    jest(),
    neutrino => {
      neutrino.config.resolve.alias.set('local', neutrino.options.source);
    },
  ],
};
// jest.config.js
const neutrino = require('neutrino');
const path = require('path');
process.env.NODE_ENV = process.env.NODE_ENV || 'test';

const config = neutrino().jest();
console.log(config);
module.exports = config;
Console output
{ rootDir: '/project-folder',
  moduleDirectories: [ 'node_modules' ],
  moduleFileExtensions: [ 'wasm', 'jsx', 'js', 'json' ],
  moduleNameMapper:
   { '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
      '/project-folder/node_modules/@neutrinojs/jest/src/file-mock.js',
     '\\.(css|less|sass|scss)$':
      '/project-folder/node_modules/@neutrinojs/jest/src/style-mock.js',
     '^local$':
      '/project-folder/src$1' },
  bail: true,
  collectCoverageFrom: [ 'src/**/*.{mjs,jsx,js}' ],
  testEnvironment: 'node',
  testRegex: 'src/.*(_test|_spec|\\.test|\\.spec)\\.(mjs|jsx|js)$',
  verbose: false,
  transform:
   { '\\.(mjs|jsx|js)$':
      '/project-folder/node_modules/@neutrinojs/jest/src/transformer.js' } }
Temporary solution
// jest.config.js
const neutrino = require('neutrino');
const path = require('path');
process.env.NODE_ENV = process.env.NODE_ENV || 'test';

const config = neutrino().jest();
delete config.moduleNameMapper['^local$']
config.moduleNameMapper['^local/(.*)$'] = path.join(__dirname, 'src/$1')
module.exports = config;

lucasMontenegro avatar Apr 09 '20 16:04 lucasMontenegro