我正在研究使用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和整个堆栈开发都很新,所以任何帮助都会受到赞赏。
答案 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
总是返回一个数组