Babel 无法从本地自定义模块使用 Flow 解析文件.失败并显示以下错误:"模块构建失败.语法错误:意外令



所以我正在创建一个 Web 应用程序,我们将调用WebApp,这是一个 React 模块,它使用来自自定义 React 模块的组件,我们将调用CustomModule,它也位于我的本地机器上。我一直在尝试从WebApp中的CustomModule导入某些组件,并且遇到了以下错误,该错误在WebApp中运行webpack-dev-server -d时出现:

ERROR in /CustomModule/Components/LoadingSpinner/LoadingSpinner.jsx
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /CustomModule/Components/LoadingSpinner/LoadingSpinner.jsx: Unexpected token, expected ";" (11:17)
9 |
10 | export const Spinner = () => {
> 11 |     var imgStyle : object = {
|                  ^
12 |         height:"75%",
13 |         padding:"2px 0 0 2px"
14 |     } ;
at Parser.raise (/WebApp/node_modules/@babel/parser/lib/index.js:3851:17)
at Parser.unexpected (/WebApp/node_modules/@babel/parser/lib/index.js:5167:16)
at Parser.semicolon (/WebApp/node_modules/@babel/parser/lib/index.js:5149:40)
at Parser.parseVarStatement (/WebApp/node_modules/@babel/parser/lib/index.js:7763:10)
at Parser.parseStatementContent (/WebApp/node_modules/@babel/parser/lib/index.js:7358:21)
at Parser.parseStatement (/WebApp/node_modules/@babel/parser/lib/index.js:7291:17)
at Parser.parseBlockOrModuleBlockBody (/WebApp/node_modules/@babel/parser/lib/index.js:7868:25)
at Parser.parseBlockBody (/WebApp/node_modules/@babel/parser/lib/index.js:7855:10)
at Parser.parseBlock (/WebApp/node_modules/@babel/parser/lib/index.js:7839:10)
at Parser.parseFunctionBody (/WebApp/node_modules/@babel/parser/lib/index.js:6909:24)
@ /CustomModule/Components/LoadingSpinner/index.js 1:0-65 1:0-65
@ /CustomModule/Components/index.js
@ ./ClientScripts/DataExplorer/Dashboard/containers/DashboardContent.jsx
@ ./ClientScripts/DataExplorer/Dashboard/index.js
@ ./ClientScripts/Route/RouteConfig.jsx
@ ./ClientScripts/Route/index.js
@ ./ClientScripts/Main.jsx
@ ./ClientScripts/index.js
@ multi (webpack)-dev-server/client?http://localhost:9000 ./ClientScripts/index.js

两个模块都使用Flowbabelwebpack。我已经在每个模块中相应地设置了package.jsonwebpack.config.js.flowconfig.babelrc文件。然后我象征性地CustomModule链接到WebApp使用npm link.我使用webpack构建CustomModule,然后尝试构建包含 import 语句以使用CustomModule中的组件的WebApp

版本

node: v9.0.0
npm: 5.5.1
@babel/cli: 7.2.3
@babel/core: 7.4.3
@babel/preset-flow: 7.0.0
babel-loader: 8.0.5
flow: 0.2.3
flow-webpack-plugin: 1.2.0
webpack: 4.16.5

WebApp webpack.config.js

const webpack = require('webpack');
const path = require('path');
const glob = require('glob');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const FlowWebpackPlugin = require('flow-webpack-plugin');
module.exports = {
entry: {
vendor: ['babel-polyfill', 'react', 'react-dom'],
annotationService: glob.sync('./ClientScripts/AnnotationService/*.js'),
repositoryService: glob.sync('./ClientScripts/RepositoryService/*.js'),
timelineService: glob.sync('./ClientScripts/TimelineService/*.js'),
filterService: glob.sync('./ClientScripts/DataExplorer/Dashboard/FilterServices/*.js'),
platform: './ClientScripts/index.js',
objects: glob.sync("./ClientScripts/RepositoryService/Objects/*.js"),
sass: './sass/main.scss'
},
output: {
path: path.join(__dirname, 'reactDist'),
filename: 'js/[name].js',
sourceMapFilename: 'map/[name].map'
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\/]node_modules[\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
},
resolve: {
alias: {
Interfaces: path.resolve(__dirname, 'ClientScripts/Interfaces/'),
Layout: path.resolve(__dirname, 'ClientScripts/Layout/'),
Navigation: path.resolve(__dirname, 'ClientScripts/Navigation/'),
Redux: path.resolve(__dirname, 'ClientScripts/Redux/'),
RepositoryService: path.resolve(__dirname, 'ClientScripts/RepositoryService/'),
TimelineService: path.resolve(__dirname, 'ClientScripts/TimelineService/'),
FilterService: path.resolve(__dirname, 'ClientScripts/DataExplorer/Dashboard/FilterServices/'),
AnnotationService: path.resolve(__dirname, 'ClientScripts/AnnotationService/'),
Route: path.resolve(__dirname, 'ClientScripts/Route/'),
Timeline: path.resolve(__dirname, 'ClientScripts/Timeline/'),
TimelineEditor: path.resolve(__dirname, 'ClientScripts/TimelineEditor/'),
Utilities: path.resolve(__dirname, 'ClientScripts/jsutils/'),
ReactUtils: path.resolve(__dirname, 'ClientScripts/reactUtils/'),
Images: path.resolve(__dirname, 'img/'),
},
symlinks: true
},
target: 'web',
node: {
fs: "empty"
},
externals: {
'winston': 'require("winston")
},
module: {
rules: [
{ test: /.js$/, loader: 'babel-loader' },
{ test: /.jsx$/, loader: 'babel-loader' },
{ test: /.env$/, loader: "file-loader?name=index.[ext]", exclude: [/node_modules/] },
{
test: /.scss$|.css$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract({
use: [{
loader: "css-loader",
options: {
minimize: true
}
},'sass-loader']
})
},
{ test: /.(jpe?g|png|gif|svg)$/,
loader: 'file-loader?name=img/[name].[ext]?',
options: {
name (file) {
if (process.env.environment === 'prod') {
return '[path][name].[hash].[ext]'
}
return '[path][name].[ext]'
}
}
}
]
},
plugins: [
new ExtractTextPlugin({ filename: 'css/timeline.[md5:contenthash:hex:20].css', disable: false, allChunks: true }),
new FlowWebpackPlugin()
]
}

WebApp .flowconfig

[ignore]
.*/node_modules/flow-webpack-plugin/.*
.*/node_modules/.*.json$
.*/node_modules/.staging/.*
[libs]
flow-typed
[options]
module.name_mapper='^Interfaces/(.*)$' -> '<PROJECT_ROOT>/ClientScripts/Interfaces/1'
module.name_mapper='^Layout/(.*)$' -> '<PROJECT_ROOT>/ClientScripts/Layout/1'
module.name_mapper='^Navigation/(.*)$' -> '<PROJECT_ROOT>/ClientScripts/Navigation/1'
module.name_mapper='^Redux/(.*)$' -> '<PROJECT_ROOT>/ClientScripts/Redux/1'
module.name_mapper='^RepositoryService/(.*)$' -> '<PROJECT_ROOT>/ClientScripts/RepositoryService/1'
module.name_mapper='^Route/(.*)$' -> '<PROJECT_ROOT>/ClientScripts/Route/1'
module.name_mapper='^Timeline/(.*)$' -> '<PROJECT_ROOT>/ClientScripts/Timeline/1'
module.name_mapper='^TimelineEditor/(.*)$' -> '<PROJECT_ROOT>/ClientScripts/TimelineEditor/1'
module.name_mapper='^Utilities/(.*)$' -> '<PROJECT_ROOT>/ClientScripts/jsutils/1'
module.name_mapper='^Images/(.*)$' -> '<PROJECT_ROOT>/img/1'
module.file_ext=.js
module.file_ext=.jsx
module.file_ext=.svg
module.file_ext=.json

CustomModule webpack.config.js

const webpack = require('webpack');
const path = require('path');
const glob = require('glob');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const FlowWebpackPlugin = require('flow-webpack-plugin');
module.exports = {
entry: {
vendor: ['babel-polyfill', 'react', 'react-dom'],
components: './Components/index.js',
sass: './sass/main.scss'
},
output: {
path: path.join(__dirname, 'reactDist'),
filename: 'js/[name].js',
sourceMapFilename: 'map/[name].map'
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\/]node_modules[\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
},
resolve: {
alias: {
Components: path.resolve(__dirname, 'Components/'),
Images: path.resolve(__dirname, 'img/'),
Utilities: path.resolve(__dirname, 'Utilities/')
},
// extensions: ['', '.js', '.jsx']
},
target: 'web',
node: {
fs: "empty"
},
externals: {
'winston': 'require("winston")'
},
module: {
rules: [
{ test: /.js$/, loader: 'babel-loader', exclude: [/node_modules/] },
{
test: /.jsx$/,
loader: 'babel-loader',
exclude: [/node_modules/],
query: {
presets: ['@babel/preset-flow']
}
},
{ test: /.env$/, loader: "file-loader?name=index.[ext]", exclude: [/node_modules/] },
{
test: /.scss$|.css$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract({
use: [{
loader: "css-loader",
options: {
minimize: true
}
},'sass-loader']
})
},
{
test: /.(jpe?g|png|gif|svg)$/,
loader: 'file-loader?name=img/[name].[ext]?',
options: {
name (file) {
if (process.env.environment === 'prod') {
return '[path][name].[hash].[ext]'
}
return '[path][name].[ext]'
}
}
}
]
},
plugins: [
new ExtractTextPlugin({ filename: 'css/timeline.[md5:contenthash:hex:20].css', disable: false, allChunks: true }),
new FlowWebpackPlugin(),
]
}

自定义模块 .flowconfig

[ignore]
.*/node_modules/flow-webpack-plugin/.*
.*/node_modules/.*.json$
.*/node_modules/.staging/.*
[libs]
flow-typed
[options]
module.name_mapper='^Components/(.*)$' -> '<PROJECT_ROOT>/Components/1'
module.name_mapper='^Images/(.*)$' -> '<PROJECT_ROOT>/img/1'
module.name_mapper='^Utilities/(.*)$' -> '<PROJECT_ROOT>/Utilities/1'
module.file_ext=.js
module.file_ext=.jsx
module.file_ext=.svg
module.file_ext=.json

两个模块使用相同的 .babelrc

/*
./.babelrc
*/
{
"presets":[
"@babel/preset-env", "@babel/preset-react", "@babel/preset-flow"
],
"plugins": [
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
"@babel/plugin-transform-flow-strip-types",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-json-strings",
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
"@babel/plugin-proposal-function-sent",
"@babel/plugin-proposal-export-namespace-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-throw-expressions"
]
}

我希望webpack-dev-server的结果不会产生任何错误,而不是在 babel 解析期间抛出的Module build failed错误。

Webpackbabel插件无法解析自定义LoadingSpinner.jsx文件中的imgStyle对象声明。这是因为您的样式对象(对于微调器)在样式对象声明中滑动了一个:。这会导致分析错误因为这JavaScript语法无效,因此您会收到以下语法错误:

语法错误:/自定义模块/组件/加载微调器/加载微调器.jsx:意外标记,预期的";"(11:17)

查看堆栈跟踪,它指出第 11 行是罪魁祸首:

10 | export const Spinner = () => {
> 11 |     var imgStyle : object = {
|                  ^
12 |         height:"75%",
13 |         padding:"2px 0 0 2px"
14 |     } ;

请注意此行:var imgStyle : object = { // extra colon before the object declaration

只需删除自定义微调器样式对象声明中的:webpackbabel插件现在应该能够成功解析此文件。如下所示:

var imgStyleObject = {
height:"75%",
padding:"2px 0 0 2px"
};

希望对您有所帮助!

最新更新