question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Can not ignore unicorn/no-null in some case

See original GitHub issue

.eslintrc.js: rules 'unicorn/no-null': 0,

code (Note the line of code marked FIXME):

// import 'core-js/stable';
// import 'regenerator-runtime/runtime';
import uniq from 'lodash/uniq';
import React from 'react';
import ReactDom from 'react-dom';
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import { createBrowserHistory } from 'history';
import { ConnectedRouter, connectRouter, routerMiddleware } from 'connected-react-router';
import createSagaMiddleware from 'redux-saga';

import modelManager, { getReducer, getSaga, SHOW, HIDE } from '@/models';
import initRequest from '@/utils/request';
import App from '@/routes/App';

const history = createBrowserHistory();

// Build the middleware for intercepting and dispatching navigation actions
const reduxRouterMiddleware = routerMiddleware(history);
const reduxSagaMiddleware = createSagaMiddleware();

// window.__REDUX_DEVTOOLS_EXTENSION__
// const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
//   //
// }) || compose
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const connectRouterReducer = connectRouter(history);

const allModelKeys = modelManager.keys();

const injectedModels = [];
const loadModels = keys => {
  injectedModels.push(
    ...uniq(keys)
      .filter(key => !injectedModels.some(m => m.namespace === key) && allModelKeys.includes(key))
      .map(key => {
        const model = modelManager.load(key);
        if (model == null) { // **FIXME target line 1** 
          throw new Error(`[${key}]: Model load fails`);
        }
        return model.default || model;
      })
      .filter(Boolean)
  );
};

// redux 初始化默认加载的model
const initialModels = ['global', 'login', 'user', 'venue', 'datatable', 'extfield'];

loadModels(initialModels);

const createNewReducers = () => {
  const reducers = {};
  injectedModels.forEach(model => {
    reducers[model.namespace] = getReducer(model);
  });
  return combineReducers({
    ...reducers,
    loading: (state, action) => {
      switch (action.type) {
        case SHOW:
        case HIDE:
          return {
            ...state,
            effects: {
              ...state.effects,
              [action.payload.actionType]: action.type === SHOW,
            },
          };
        default:
          return state || {};
      }
    },
    router: connectRouterReducer,
  });
};

const runSaga = (keys = [], hasLoadKeys = []) => {
  injectedModels
    .filter(model => keys.includes(model.namespace) && !hasLoadKeys.includes(model.namespace))
    .forEach(model => {
      reduxSagaMiddleware.run(getSaga(model));
    });
};

const store = createStore(
  createNewReducers(),
  // preloadedState
  {
    loading: {
      effects: {},
    },
  },
  composeEnhancers(
    applyMiddleware(
      reduxRouterMiddleware,
      // promiseMiddleware
      // eslint-disable-next-line unicorn/consistent-function-scoping
      () => next => action => {
        const { type } = action;
        if (typeof type === 'string') {
          const [namespace, effectName] = type.split('/');
          // model.effects 的一定都是 effect
          if (
            injectedModels
              .filter(model => model.namespace === namespace)
              .some(model => model.effects && model.effects[effectName])
          ) {
            return new Promise((resolve, reject) => {
              next({
                ...action,
                _resolve: resolve,
                _reject: reject,
              });
            });
          }
        }
        return Promise.resolve(next(action));
      },
      reduxSagaMiddleware
    )
  )
);

initRequest(store.dispatch, store);

runSaga(initialModels, []);

const appManager = {
  injectModel: model => {
    if (model == null || model.length === 0) { // **FIXME target line 2**
      return;
    }
    const hasLoadKeys = injectedModels.map(m => m.namespace);
    loadModels(model);
    store.replaceReducer(createNewReducers());
    runSaga(model, hasLoadKeys);
  },
};

ReactDom.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <App app={appManager} />
    </ConnectedRouter>
  </Provider>,
  // eslint-disable-next-line unicorn/prefer-query-selector
  document.getElementById('root')
);

It report

image

If I fix any one error, the other will no longer report the error.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
fiskercommented, Jun 1, 2020

@kevinoid

Thank you for your explanation.

I think this is a bug in eslint, if (foo == null) is equals to if (foo == undefined), why allow null, but not allow undefined.

anyway, since that eqeqeq is not going to change, I’m adding an option to ignore == and != on our side.

0reactions
amakhrovcommented, May 11, 2022

Obviously, eslint team is not willing to make this change: https://github.com/eslint/eslint/issues/13537#issuecomment-677824969

So as it stands right now, the two rules (eqeqeq and no-null) are generally conflicting. Perhaps we should document it, and suggest some workarounds, if any?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Can not ignore unicorn/no-null in some case #703 - Issuehunt
One reason it might be preferable to allow == null as a special case is that the built-in eqeqeq rule has options (...
Read more >
eslint-plugin-unicorn/readme.md - UNPKG
The CDN for eslint-plugin-unicorn. ... Do not manually modify this table. ... 163, | [no-console-spaces](docs/rules/no-console-spaces.md) | Do not use ...
Read more >
eslint-plugin-unicorn - npm
Name Description 💼 🚫 🔧 💡 consistent‑destructuring Use destructured variables over properties. ✓ 🔧 💡 custom‑error‑definition Enforce correct Error subclassing. ✓ 🔧 empty‑brace‑spaces Enforce no spaces...
Read more >
Unicorns Do Exist: A Tutorial on “Proving” the Null Hypothesis
To use our original example, no one has ever seen such a unicorn (at least while sober), but we cannot prove that it...
Read more >
eslint-plugin-unicorn - npm Package Health Analysis - Snyk
Do not use a for loop that can be replaced with a for-of loop. ✓,. no-hex-escape, Enforce the use of Unicode escapes instead...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found