我使用create-react-app创建了一个项目。在./src
文件夹中描述了前端。我在项目的根目录下有一个名为server.js
的文件。该文件正在使用express描述API。
我想要一个包含模型的文件夹,该模型将在前端(在./src
下)和后端(在./server.js
下)之间共享。
我要分享的一个类的示例:
export default class DataModel {
constructor(name) {
this.name = name;
}
}
如果将此类放在./src/models/DataModel.js
下,则可以通过使用./src
在import DataModel from '../models/DataModel';
内使用它,但是我不能在./server.js
内使用它,因为它给了我出现以下错误:
意外的令牌导出
而且我不能将类直接置于项目的根目录下,因为create-react-app不接受来自./src
文件夹外部的导入,并且会给我以下错误:
未找到模块:您试图导入不在项目src /目录下的../../DataModel。不支持src /以外的相对导入。
我尝试使用react-app-rewired
,但没有成功。
我的package.json已更新:
{
//...
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
},
"devDependencies": {
"react-app-rewired": "^2.1.0"
}
}
然后我在项目的根目录(与package.json和DataModel类相同的级别)上添加了文件config-overrides.js
。
/* config-overrides.js */
module.exports = function override(config, env) {
delete config.resolve.plugins.ModuleScopePlugin;
return config;
}
但是我仍然遇到相同的问题:
未找到模块:您试图导入不在项目src /目录下的../../DataModel。不支持src /以外的相对导入。
我记录了通过config
函数传递的override
,这是我得到的:
{
"mode": "development",
"devtool": "cheap-module-source-map",
"entry": [
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\react-dev-utils\\webpackHotDevClient.js",
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\src\\index.js"
],
"output": {
"pathinfo": true,
"filename": "static/js/bundle.js",
"chunkFilename": "static/js/[name].chunk.js",
"publicPath": "/"
},
"optimization": {
"splitChunks": {
"chunks": "all",
"name": false
},
"runtimeChunk": true
},
"resolve": {
"modules": [
"node_modules"
],
"extensions": [
".web.mjs",
".mjs",
".web.js",
".js",
".json",
".web.jsx",
".jsx"
],
"alias": {
"react-native": "react-native-web"
},
"plugins": [
{
"topLevelLoader": {}
},
{
"appSrcs": [
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\src"
],
"allowedFiles": {}
}
]
},
"resolveLoader": {
"plugins": [
{}
]
},
"module": {
"strictExportPresence": true,
"rules": [
{
"parser": {
"requireEnsure": false
}
},
{
"test": {},
"enforce": "pre",
"use": [
{
"options": {
"formatter": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\react-dev-utils\\eslintFormatter.js",
"eslintPath": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\eslint\\lib\\api.js",
"baseConfig": {
"extends": [
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\eslint-config-react-app\\index.js"
],
"settings": {
"react": {
"version": "999.999.999"
}
}
},
"ignore": false,
"useEslintrc": false
},
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\eslint-loader\\index.js"
}
],
"include": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\src"
},
{
"oneOf": [
{
"test": [
{},
{},
{},
{}
],
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\url-loader\\dist\\cjs.js",
"options": {
"limit": 10000,
"name": "static/media/[name].[hash:8].[ext]"
}
},
{
"test": {},
"include": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\src",
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\babel-loader\\lib\\index.js",
"options": {
"customize": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\babel-preset-react-app\\webpack-overrides.js",
"babelrc": false,
"configFile": false,
"presets": [
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\babel-preset-react-app\\index.js"
],
"cacheIdentifier": "development:babel-plugin-named-asset-import@0.2.3:babel-preset-react-app@6.1.0:react-dev-utils@6.1.1:react-scripts@2.1.1",
"plugins": [
[
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\babel-plugin-named-asset-import\\index.js",
{
"loaderMap": {
"svg": {
"ReactComponent": "@svgr/webpack?-prettier,-svgo![path]"
}
}
}
]
],
"cacheDirectory": true,
"cacheCompression": false
}
},
{
"test": {},
"exclude": {},
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\babel-loader\\lib\\index.js",
"options": {
"babelrc": false,
"configFile": false,
"compact": false,
"presets": [
[
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\babel-preset-react-app\\dependencies.js",
{
"helpers": true
}
]
],
"cacheDirectory": true,
"cacheCompression": false,
"cacheIdentifier": "development:babel-plugin-named-asset-import@0.2.3:babel-preset-react-app@6.1.0:react-dev-utils@6.1.1:react-scripts@2.1.1",
"sourceMaps": false
}
},
{
"test": {},
"exclude": {},
"use": [
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\style-loader\\index.js",
{
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\css-loader\\index.js",
"options": {
"importLoaders": 1
}
},
{
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\postcss-loader\\src\\index.js",
"options": {
"ident": "postcss"
}
}
]
},
{
"test": {},
"use": [
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\style-loader\\index.js",
{
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\css-loader\\index.js",
"options": {
"importLoaders": 1,
"modules": true
}
},
{
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\postcss-loader\\src\\index.js",
"options": {
"ident": "postcss"
}
}
]
},
{
"test": {},
"exclude": {},
"use": [
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\style-loader\\index.js",
{
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\css-loader\\index.js",
"options": {
"importLoaders": 2
}
},
{
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\postcss-loader\\src\\index.js",
"options": {
"ident": "postcss"
}
},
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\sass-loader\\lib\\loader.js"
]
},
{
"test": {},
"use": [
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\style-loader\\index.js",
{
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\css-loader\\index.js",
"options": {
"importLoaders": 2,
"modules": true
}
},
{
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\postcss-loader\\src\\index.js",
"options": {
"ident": "postcss"
}
},
"C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\sass-loader\\lib\\loader.js"
]
},
{
"exclude": [
{},
{},
{}
],
"loader": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules\\file-loader\\dist\\cjs.js",
"options": {
"name": "static/media/[name].[hash:8].[ext]"
}
}
]
}
]
},
"plugins": [
{
"options": {
"template": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\public\\index.html",
"templateContent": false,
"filename": "index.html",
"hash": false,
"inject": true,
"compile": true,
"favicon": false,
"minify": false,
"cache": true,
"showErrors": true,
"chunks": "all",
"excludeChunks": [],
"chunksSortMode": "auto",
"meta": {},
"title": "Webpack App",
"xhtml": false
},
"version": 4
},
{
"replacements": {
"NODE_ENV": "development",
"PUBLIC_URL": "",
"REACT_APP_DEFAULT_LANGUAGE": "fr"
}
},
{
"appPath": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT"
},
{
"definitions": {
"process.env": {
"NODE_ENV": "\"development\"",
"PUBLIC_URL": "\"\"",
"REACT_APP_DEFAULT_LANGUAGE": "\"fr\""
}
}
},
{
"options": {},
"fullBuildTimeout": 200,
"requestTimeout": 10000
},
{
"options": {},
"pathCache": {},
"fsOperations": 0,
"primed": false
},
{
"nodeModulesPath": "C:\\Users\\me\\Documents\\nodejs\\MY_PROJECT\\node_modules"
},
{
"options": {
"resourceRegExp": {},
"contextRegExp": {}
}
},
{
"opts": {
"publicPath": "/",
"basePath": "",
"fileName": "asset-manifest.json",
"transformExtensions": {},
"writeToFileEmit": false,
"seed": null,
"filter": null,
"map": null,
"generate": null,
"sort": null
}
}
],
"node": {
"dgram": "empty",
"fs": "empty",
"net": "empty",
"tls": "empty",
"child_process": "empty"
},
"performance": false
}
我在调用delete
操作之前记录了日志,我们可以看到它们不是ModuleScopePlugin
。那么为什么它仍然失败?
欢迎任何帮助。
谢谢。
答案 0 :(得分:1)
共享代码是模块的用途。理想情况下,您会将模型打包到模块中,然后安装/导入每个代码库。为了使开发简单,您可能需要使用Lerna和Yarn(或类似替代品)的monorepo格式。
如果这超出了您项目的范围,那么我认为您应该能够在模型代码中使用CommonJS导出(如先前建议的那样),并将其保存在React app src中,并从服务器代码中获取。 / p>
intArray
:
./src/models/DataModel.js
来自React应用
class DataModel {
constructor(name) {
this.name = name;
}
}
module.exports = { DataModel };
来自服务器
import { DataModel } from "./models/DataModel";
================================================ ========================
据我所知,我们在这里遇到了一些深层的js模块伏都教徒。
我上面建议的代码可在codesandbox中使用,但不能在本地使用。
我尝试将react-scripts和react版本与codeandbox中的匹配,但没有成功。我只能假设codesandbox有自己的缓解问题的应对机制。
一旦使用commonjs导出在模块中定义了类,就对
感到奇怪 const { DataModel } = require("./src/models/DataModel");
和module.exports = { DataModel };
给出import {DataModel}
Attempted import error: 'DataModel' is not exported from '../models/DataModel'.
和module.exports = { DataModel };
给出require
和
TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
和exports.DataModel = DataModel;
给出require
不过,将ReferenceError: exports is not defined
换成老式的“班级”,然后从我们的应用程序中class
替换模块,一切都会按预期进行。
require
这似乎与webpack / babel / et al所执行的所有魔术有关,以处理各种浮动的模块格式,但是我实在无法确定。
有一秒钟我以为这可以解释它,但是..却没有。https://medium.com/webpack/webpack-4-import-and-commonjs-d619d626b655