React.JS:TypeError:无法读取findLoader中未定义的属性“filter”

时间:2017-05-19 21:54:54

标签: reactjs

我正在研究使用react.JS制作yelp克隆的教程(https://www.fullstackreact.com/articles/react-tutorial-cloning-yelp/#routing)。我一直遇到错误:

  

TypeError:无法读取未定义的属性“过滤器”       在findLoader

我的webpack.config.js文件中出现错误,并且不允许我运行程序或建立与localhost的连接。

const NODE_ENV = process.env.NODE_ENV || 'development';
const dotenv = require('dotenv');

const webpack = require('webpack');
const path = require('path');

const join = path.join;
const resolve = path.resolve;

const getConfig = require('hjs-webpack');

const isDev = NODE_ENV === 'development';
const isTest = NODE_ENV === 'test';

// devServer config
const devHost   = process.env.HOST || 'localhost';
const devPort   = process.env.PORT || 3000;

const setPublicPath = process.env.SET_PUBLIC_PATH !== 'false';
const publicPath  = (isDev && setPublicPath) ? `//${devHost}:${devPort}/` : '';

const root = resolve(__dirname);
const src = join(root, 'src');
const modules = join(root, 'node_modules');
const dest = join(root, 'dist');
const css = join(src, 'styles');

var config = getConfig({
  isDev: isDev || isTest,
  in: join(src, 'app.js'),
  out: dest,
  html: function (context) {
    return {
      'index.html': context.defaultTemplate({
        title: 'FoodFinder',
        publicPath,
        meta: {}
      })
    };
  }
});

// ENV variables
const dotEnvVars = dotenv.config();
const environmentEnv = dotenv.config({
  path: join(root, 'config', `${NODE_ENV}.config.js`),
  silent: true
});
const envVariables =
    Object.assign({}, dotEnvVars, environmentEnv);

const defines =
  Object.keys(envVariables)
  .reduce((memo, key) => {
    const val = JSON.stringify(envVariables[key]);
    memo[`__${key.toUpperCase()}__`] = val;
    return memo;
  }, {
    __NODE_ENV__: JSON.stringify(NODE_ENV),
    __DEBUG__: isDev
  });

config.plugins = [
  new webpack.DefinePlugin(defines)
].concat(config.plugins);
// END ENV variables

// CSS modules
const cssModulesNames = `${isDev ? '[path][name]__[local]__' : ''}[hash:base64:5]`;

const matchCssLoaders = /(^|!)(css-loader)($|!)/;

const findLoader = (loaders, match) => {
  const found = loaders.filter(l => l && l.loader && l.loader.match(match));
  return found ? found[0] : null;
};

// existing css loader
const cssloader =
  findLoader(config.module.loaders, matchCssLoaders);

const newloader = Object.assign({}, cssloader, {
  test: /\.module\.css$/,
  include: [src],
  loader: cssloader.loader.replace(matchCssLoaders, `$1$2?modules&localIdentName=${cssModulesNames}$3`)
});
config.module.loaders.push(newloader);
cssloader.test = new RegExp(`[^module]${cssloader.test.source}`);
cssloader.loader = newloader.loader;

config.module.loaders.push({
  test: /\.css$/,
  include: [modules],
  loader: 'style!css'
});

// CSS modules

// postcss
config.postcss = [].concat([
  require('precss')({}),
  require('autoprefixer')({}),
  require('cssnano')({})
]);

// END postcss

// Roots
config.resolve.root = [src, modules];
config.resolve.alias = {
  css: join(src, 'styles'),
  containers: join(src, 'containers'),
  components: join(src, 'components'),
  utils: join(src, 'utils'),
  styles: join(src, 'styles')
};
// end Roots

// Dev
if (isDev) {
  config.devServer.port = devPort;
  config.devServer.hostname = devHost;
}

// Testing
if (isTest) {
  config.externals = {
    'react/addons': true,
    'react/lib/ReactContext': true,
    'react/lib/ExecutionEnvironment': true
  };

  config.module.noParse = /[/\\]sinon\.js/;
  config.resolve.alias.sinon = 'sinon/pkg/sinon';

  config.plugins = config.plugins.filter(p => {
    const name = p.constructor.toString();
    const fnName = name.match(/^function (.*)\((.*\))/);

    const idx = [
      'DedupePlugin',
      'UglifyJsPlugin'
    ].indexOf(fnName[1]);
    return idx < 0;
  });
}
// End Testing

    module.exports = config;

我对React.JS和整个堆栈开发都很新,所以任何帮助都会受到赞赏。

2 个答案:

答案 0 :(得分:1)

@Tyler Sebastian提供的答案将不起作用,因为const cssloader = findLoader(...);用于根据您正在使用的教程查找现有的cssloader,而正在推送的新加载器将替换它。

该错误,根据该教程的注释,似乎是本教程中使用的技术已更新,导致其中断。评论者建议的解决方案是删除您的node_modules目录,将webpack.config.js文件替换为教程存储库中提供的文件,然后重新安装依赖项(从本质上恢复为该技术的较早版本)。

我认为这不是解决问题的好方法,因为目的是要学习有用的东西,不仅使它起作用,而且应该起作用。由于我是一个经验不足的React开发人员,尝试使用此过时的教程,因此我无法提出更好的解决方案

编辑:我已经尝试了评论建议的解决方案,但是它不起作用。

答案 1 :(得分:0)

一个可能的原因是你在找到装载机之前注册&#34;装载机

const cssloader = findLoader(config.module.loaders, matchCssLoaders);

在使用config.module.loaders.push(...)之前出现。很难说,因为您通过函数调用初始化config所以我不确定初始值是什么。

如果您预计config.modules的类型为null | loader[],则可以将findLoader中的第一行更改为const found = (loaders || []).filter(...)

另外,

const findLoader = (loaders, match) => {
  const found = loaders.filter(l => l && l.loader && l.loader.match(match));
  return found ? found[0] : null;
};

没有做你认为会做的事情......考虑

let x = [] // an empty array
console.log(x ? "not empty" : "empty")

> "not empty"

它不像Python3,其中一个空数组== False,而filter总是返回一个数组