ReactJS: Importing symlinked components error: Module parse failed: Unexpected token: You may need an appropriate loader to handle this file type
ReactJS: Importing symlinked components error: Module parse failed: Unexpected token: You may need an appropriate loader to handle this file type
我正在编写一个 React 组件库,我想在没有太多开销(bit、create-react-library、generact 等)且无需发布的情况下将其用于其他项目。我想使用 npm install ../shared_lib
将它作为 /node_modules
中的符号链接添加到我的项目中。此命令将符号链接添加到项目 node_modules。在我的 shared_lib 中,我只是测试了 export default
a <div></div>
:
import React from 'react';
const TryTest = function() {
return (
<div>
TryTest
</div>
)
}
export default TryTest;
当我将组件导入我的 working 项目时,我面临的问题是以下错误:
import TryTest from 'shared_lib';
错误:
ERROR in ../shared_lib/src/index.js 6:4
Module parse failed: Unexpected token (6:4)
You may need an appropriate loader to handle this file type.
| const TryTest = function() {
| return (
> <div>
| TryTest
| </div>
@ ./src/App.js 27:0-33 28:12-19
@ ./src/index.js
@ multi babel-polyfill ./src/index.js
如果我从 shared_lib
导入任何东西而不是带有 jsx 的文件 - 例如,字符串或函数等 - 它工作正常。
编辑: 应用程序 webpack 已解析对象的符号链接属性设置为 false:
resolve: {
symlinks: false
},
编辑: 在应用下面答案中的解决方案后 (),我后来将 symlinks prop 改回 true。我不需要将其设置为 false 即可使解决方案正常工作并呈现 shared_lib
个组件。
我的应用加载器:
{
test: /\.jsx?$/,
include: [
path.join( __dirname, 'src'), // app/src
fs.realpathSync(__dirname + '/node_modules/shared_lib'), // app/node_modules/shared_lib/dist/shared_lib.js
],
exclude: /node_modules/,
use: [ 'babel-loader' ]
}
编辑: 当我在下面的答案中应用解决方案时,加载器现在看起来像这样:
{
test: /\.jsx?$/,
include: [
path.join( __dirname, 'src'), // app/src
fs.realpathSync(__dirname + '/node_modules/shared_lib'), // app/node_modules/shared_lib/dist/shared_lib.js
],
exclude: /node_modules/,
use: [ {
loader: 'babel-loader',
options: require("./package.json").babel
}
]
}
应用程序的当前 .babelrc 设置(我也尝试删除 .babelrc 并在 package.json 中包含预设,结果相同):
{
"presets": [ "@babel/preset-react", "@babel/preset-env"]
}
**编辑:应用下面答案中的解决方案后,我最终将 babel 预设放回 package.json.
"babel": {
"presets": [
"@babel/preset-react",
"@babel/preset-env"
]
},
我研究了 while 以找到解决此问题的方法,显然 webpack 在捆绑符号链接反应组件时存在问题? 我没有使用 create-react-app。
因此,我尝试在将 shared_lib 导入项目之前将其捆绑,只是为了看看会发生什么。这是最终的 webpack 配置(我也尝试了其他配置):
const pkg = require('./package.json');
const path = require('path');
const buildPath = path.join( __dirname, 'dist' );
const clientPath = path.join( __dirname, 'src');
const depsPath = path.join( __dirname, 'node_modules');
const libraryName = pkg.name;
module.exports = [
'cheap-module-source-map'
].map( devtool => ({
bail: true,
mode: 'development',
entry: {
lib : [ 'babel-polyfill', path.join( clientPath, 'index.js' ) ]
},
output: {
path: buildPath,
filename: 'shared_lib.js',
libraryTarget: 'umd',
publicPath: '/dist/',
library: libraryName,
umdNamedDefine: true
},
// to avoid bundling react
externals: {
'react': {
commonjs: 'react',
commonjs2: 'react',
amd: 'React',
root: 'React'
}
},
module: {
rules: [
{
test: /\.jsx?$/,
include: [
clientPath
],
exclude: /node_modules/,
use: [ 'babel-loader' ],
},
]
},
devtool,
optimization: {
splitChunks: {
chunks: 'all',
},
}
}));
而 package.json 为 shared_lib
{
"name": "shared_lib",
"version": "1.0.0",
"description": "",
"main": "dist/shared_lib.js",
"scripts": {
"clean": "rm -rf dist/",
"build": "$(npm bin)/webpack --config ./webpack.config.js",
"prepublish": "npm run clean && npm run build"
},
"author": "",
"license": "ISC",
"peerDependencies": {
"react": "^16.8.6"
},
"devDependencies": {
"react": "^16.8.6",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
"@babel/preset-react": "^7.9.4",
"babel-loader": "^8.1.0",
"babel-polyfill": "^6.26.0",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11"
},
"babel": {
"presets": [
"@babel/preset-react",
"@babel/preset-env"
]
}
}
包已打包,没有错误:
当我尝试以同样的方式导入组件时:
import TryTest from 'shared_lib';
console.log returns undefined
.
我的应用程序中库文件的路径很好,因为如果我删除 shared_lib/dist/shared_lib.js
中的所有内容并只写 export default 1
,我的 App.js
中的 console.log(TryTest)
将return 1
.
我尝试将 shared_lib/webpack.config
中的 libraryTarget 属性 更改为 libraryTarget: 'commonjs'
。 console.log(TryTest)
的结果变为 {shared_lib: undefined}
.
有没有人运行参与其中?
我找到了最终对我有用的东西,并将符号链接 shared_lib
渲染到应用程序。
这个答案:https://github.com/webpack/webpack/issues/1643#issuecomment-552767686
渲染符号链接的 shared_lib
组件效果很好。我没有发现使用此解决方案有任何缺点,但这是迄今为止唯一有效的解决方案。
我正在编写一个 React 组件库,我想在没有太多开销(bit、create-react-library、generact 等)且无需发布的情况下将其用于其他项目。我想使用 npm install ../shared_lib
将它作为 /node_modules
中的符号链接添加到我的项目中。此命令将符号链接添加到项目 node_modules。在我的 shared_lib 中,我只是测试了 export default
a <div></div>
:
import React from 'react';
const TryTest = function() {
return (
<div>
TryTest
</div>
)
}
export default TryTest;
当我将组件导入我的 working 项目时,我面临的问题是以下错误:
import TryTest from 'shared_lib';
错误:
ERROR in ../shared_lib/src/index.js 6:4
Module parse failed: Unexpected token (6:4)
You may need an appropriate loader to handle this file type.
| const TryTest = function() {
| return (
> <div>
| TryTest
| </div>
@ ./src/App.js 27:0-33 28:12-19
@ ./src/index.js
@ multi babel-polyfill ./src/index.js
如果我从 shared_lib
导入任何东西而不是带有 jsx 的文件 - 例如,字符串或函数等 - 它工作正常。
编辑: 应用程序 webpack 已解析对象的符号链接属性设置为 false:
resolve: {
symlinks: false
},
编辑: 在应用下面答案中的解决方案后 (shared_lib
个组件。
我的应用加载器:
{
test: /\.jsx?$/,
include: [
path.join( __dirname, 'src'), // app/src
fs.realpathSync(__dirname + '/node_modules/shared_lib'), // app/node_modules/shared_lib/dist/shared_lib.js
],
exclude: /node_modules/,
use: [ 'babel-loader' ]
}
编辑: 当我在下面的答案中应用解决方案时,加载器现在看起来像这样:
{
test: /\.jsx?$/,
include: [
path.join( __dirname, 'src'), // app/src
fs.realpathSync(__dirname + '/node_modules/shared_lib'), // app/node_modules/shared_lib/dist/shared_lib.js
],
exclude: /node_modules/,
use: [ {
loader: 'babel-loader',
options: require("./package.json").babel
}
]
}
应用程序的当前 .babelrc 设置(我也尝试删除 .babelrc 并在 package.json 中包含预设,结果相同):
{
"presets": [ "@babel/preset-react", "@babel/preset-env"]
}
**编辑:应用下面答案中的解决方案后,我最终将 babel 预设放回 package.json.
"babel": {
"presets": [
"@babel/preset-react",
"@babel/preset-env"
]
},
我研究了 while 以找到解决此问题的方法,显然 webpack 在捆绑符号链接反应组件时存在问题? 我没有使用 create-react-app。 因此,我尝试在将 shared_lib 导入项目之前将其捆绑,只是为了看看会发生什么。这是最终的 webpack 配置(我也尝试了其他配置):
const pkg = require('./package.json');
const path = require('path');
const buildPath = path.join( __dirname, 'dist' );
const clientPath = path.join( __dirname, 'src');
const depsPath = path.join( __dirname, 'node_modules');
const libraryName = pkg.name;
module.exports = [
'cheap-module-source-map'
].map( devtool => ({
bail: true,
mode: 'development',
entry: {
lib : [ 'babel-polyfill', path.join( clientPath, 'index.js' ) ]
},
output: {
path: buildPath,
filename: 'shared_lib.js',
libraryTarget: 'umd',
publicPath: '/dist/',
library: libraryName,
umdNamedDefine: true
},
// to avoid bundling react
externals: {
'react': {
commonjs: 'react',
commonjs2: 'react',
amd: 'React',
root: 'React'
}
},
module: {
rules: [
{
test: /\.jsx?$/,
include: [
clientPath
],
exclude: /node_modules/,
use: [ 'babel-loader' ],
},
]
},
devtool,
optimization: {
splitChunks: {
chunks: 'all',
},
}
}));
而 package.json 为 shared_lib
{
"name": "shared_lib",
"version": "1.0.0",
"description": "",
"main": "dist/shared_lib.js",
"scripts": {
"clean": "rm -rf dist/",
"build": "$(npm bin)/webpack --config ./webpack.config.js",
"prepublish": "npm run clean && npm run build"
},
"author": "",
"license": "ISC",
"peerDependencies": {
"react": "^16.8.6"
},
"devDependencies": {
"react": "^16.8.6",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
"@babel/preset-react": "^7.9.4",
"babel-loader": "^8.1.0",
"babel-polyfill": "^6.26.0",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11"
},
"babel": {
"presets": [
"@babel/preset-react",
"@babel/preset-env"
]
}
}
包已打包,没有错误:
当我尝试以同样的方式导入组件时:
import TryTest from 'shared_lib';
console.log returns undefined
.
我的应用程序中库文件的路径很好,因为如果我删除 shared_lib/dist/shared_lib.js
中的所有内容并只写 export default 1
,我的 App.js
中的 console.log(TryTest)
将return 1
.
我尝试将 shared_lib/webpack.config
中的 libraryTarget 属性 更改为 libraryTarget: 'commonjs'
。 console.log(TryTest)
的结果变为 {shared_lib: undefined}
.
有没有人运行参与其中?
我找到了最终对我有用的东西,并将符号链接 shared_lib
渲染到应用程序。
这个答案:https://github.com/webpack/webpack/issues/1643#issuecomment-552767686
渲染符号链接的 shared_lib
组件效果很好。我没有发现使用此解决方案有任何缺点,但这是迄今为止唯一有效的解决方案。