![](/img/trans.png)
[英]ERROR in Cannot find module 'babel-core'. using react.js, webpack, and express server
[英]How to update and consolidate babel and webpack implementations to current best practices? (Error: Cannot find module '@babel/core')
期望的行为
语境:
我正在更新几年前的一个项目,因此我之前使用的约定和包已被取代,我想让我的实现符合当前的最佳实践。
实际行为
我刚刚更新了节点( v14.18.1
)和我所有的 npm 包。
运行时:
npm run webpack
我收到错误:
(node:18300) [DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING] DeprecationWarning: Using a string as loader options is deprecated (ruleSet[1].rules[4].use[0].options)
(Use `node --trace-deprecation ...` to show where the warning was created)
(node:18300) [DEP_WEBPACK_MAIN_TEMPLATE_HASH_FOR_CHUNK] DeprecationWarning: MainTemplate.hooks.hashForChunk is deprecated (use JavascriptModulesPlugin.getCompilationHooks().chunkHash instead)
(node:18300) [DEP_WEBPACK_CHUNK_TEMPLATE_HASH_FOR_CHUNK] DeprecationWarning: ChunkTemplate.hooks.hashForChunk is deprecated (use JavascriptModulesPlugin.getCompilationHooks().chunkHash instead)
(node:18300) [DEP_WEBPACK_COMPILATION_OPTIMIZE_CHUNK_ASSETS] DeprecationWarning: optimizeChunkAssets is deprecated (use Compilation.hooks.processAssets instead and use one of Compilation.PROCESS_ASSETS_STAGE_* as stage option)
(node:18300) [DEP_WEBPACK_DEPRECATION_ARRAY_TO_SET_LENGTH] DeprecationWarning: chunk.files was changed from Array to Set (using Array property 'length' is deprecated)
(node:18300) [DEP_WEBPACK_DEPRECATION_ARRAY_TO_SET_INDEXER] DeprecationWarning: chunk.files was changed from Array to Set (indexing Array is deprecated)
assets by status 2.63 KiB [cached] 1 asset
./src/js/common.js 39 bytes [not cacheable] [built] [code generated] [1 error]
ERROR in ./src/js/common.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Cannot find module '@babel/core'
Require stack:
- D:\REPOS\my application\node_modules\babel-loader\lib\index.js
- D:\REPOS\my application\node_modules\loader-runner\lib\loadLoader.js
- D:\REPOS\my application\node_modules\loader-runner\lib\LoaderRunner.js
- D:\REPOS\my application\node_modules\webpack\lib\NormalModuleFactory.js
- D:\REPOS\my application\node_modules\webpack\lib\Compiler.js
- D:\REPOS\my application\node_modules\webpack\lib\webpack.js
- D:\REPOS\my application\node_modules\webpack\lib\index.js
- D:\REPOS\my application\node_modules\webpack-cli\lib\webpack-cli.js
- D:\REPOS\my application\node_modules\webpack-cli\lib\bootstrap.js
- D:\REPOS\my application\node_modules\webpack-cli\bin\cli.js
- D:\REPOS\my application\node_modules\webpack\bin\webpack.js
babel-loader@8 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install 'babel-loader@7'.
题
我如何摆脱上述错误,并在这样做时整合我当前的 babel/webpack 实现以使用当前的最佳实践?
可能的解决方案
这篇文章的答案,似乎得到了官方 babel 文档的支持,包括:
删除被取代的包,例如:
npm uninstall babel-core babel-cli babel-preset-env babel-preset-stage-0
安装新软件包,例如:
npm install --save-dev @babel/core @babel/cli @babel/preset-env
我犹豫要不要这样做,因为:
package.json
中的devDependencies
是:"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-loader": "^8.2.3",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "^6.5.0",
"expose-loader": "^3.1.0",
"file-loader": "^6.2.0",
"jsdoc": "^3.6.7",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"style-loader": "^3.3.1",
"uglifyjs-webpack-plugin": "^2.2.0",
"uikit": "^3.8.0",
"url-loader": "^4.1.1",
"webpack": "^5.61.0",
"webpack-cli": "^4.9.1"
我的webpack.config.json
文件引用babel-loader
的options: { presets: ["env", "stage-0"] }
webpack.config.json
options: { presets: ["env", "stage-0"] }
我有一个.babelrc
文件
所以我不确定对devDependencies
更改devDependencies
会弄乱webpack
或babelrc
配置。
我试过的
Part 01: 定义相关文件和逻辑
以下是我项目中与 babel 和 webpack 相关的不同文件:
index.ntl
(引用bundle.js
html 模板)app_es6.js
(ES6 中的服务器端代码,由 babel 转译/输出到app.js
)app.js
(babel 生成的服务器端代码)common.js
(浏览器端代码,与其他资源bundle.js
被 webpack 组合成 bundle.js)bundle.js
(由 webpack 生成的浏览器端代码)package.json
.babelrc
webpack.config.js
如果我对自己的package.json
和webpack.config.js
文件的理解是正确的('我对这个地方没有记忆' - gandalf meme),我认为 webpack 仅适用于浏览器端代码( common.js
- 配置在webpack.config.js
中定义),而 babel 仅专门应用于服务器端代码( app_es6.js
- 配置在.babelrc
中定义)。
webpack.config.js
引用了以下加载器:
babel-loader - 使用 Babel 加载 ES2015+ 代码并转换为 ES5
style-loader - 将模块的导出作为样式添加到 DOM
css-loader - 加载具有解析导入的 CSS 文件并返回 CSS 代码
less-loader - 加载和编译 LESS 文件
url-loader - 将文件转换为 base64 URI
暴露加载器- 将模块全部或部分暴露给全局对象
以下是相关文件的内容:
索引.ntl
<script src="/js/bundle.js"></script>
.babelrc
{
"presets": [
[
"env",
{
"targets":
{
"node": "current"
}
}
]
]
}
webpack.config.js
const path = require('path');
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
var webpack = require("webpack");
module.exports = {
mode: "production",
entry: "./src/js/common.js", // <------ for browser-side code
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist/js")
},
module: {
rules: [{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ["env", "stage-0"]
}
}
},
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" }
]
},
{
test: /\.less$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{ loader: "less-loader" }
]
},
{
test: /\.jpg$/,
use: [
{ loader: "url-loader" }
]
},
{
test: require.resolve('jquery'),
use: [{
loader: 'expose-loader',
options: '$'
}]
},
{
test: require.resolve('js-cookie'),
use: [{
loader: 'expose-loader',
options: 'Cookies'
}]
},
{
test: require.resolve('he'),
use: [{
loader: 'expose-loader',
options: 'he'
}]
}
]
},
plugins: [
new UglifyJsPlugin(),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
'window.jQuery': 'jquery'
})
],
resolve: {
alias: {
'uikit-util': path.resolve(__dirname, 'node_modules/uikit/src/js/util')
}
}
}
包.json
{
//...
"main": "app.js",
"scripts": {
"start": "node app.js",
"build-server-file": "babel app_es6.js --out-file app.js", // <------ for server-side code
"webpack": "webpack" // <------ for browser-side code
},
//...
"dependencies": {
//...
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-loader": "^8.2.3",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "^6.5.0",
"expose-loader": "^3.1.0",
"file-loader": "^6.2.0",
"jsdoc": "^3.6.7",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"style-loader": "^3.3.1",
"uglifyjs-webpack-plugin": "^2.2.0",
"uikit": "^3.8.0",
"url-loader": "^4.1.1",
"webpack": "^5.61.0",
"webpack-cli": "^4.9.1"
}
}
第 02 部分:研究
为了加深我对 babel、webpack 和 loader 的理解:
问: babel 有什么作用?
Babel 是一个工具链,主要用于在当前和旧浏览器或环境中将 ECMAScript 2015+ 代码转换为向后兼容的 JavaScript 版本
来源: https : //babeljs.io/docs/en
问:为什么我需要 babel?
因为 node.js 还不能读取 ES6 (?)
问: webpack 有什么作用?
从本质上讲,webpack 是现代 JavaScript 应用程序的静态模块打包器。 当 webpack 处理您的应用程序时,它会从一个或多个入口点在内部构建一个依赖关系图,然后将您的项目需要的每个模块组合成一个或多个包,这些包是静态资产来为您的内容提供服务。
来源: https : //webpack.js.org/concepts
问:什么是 webpack 加载器?
加载器是应用于模块源代码的转换。 它们允许您在导入或“加载”文件时对文件进行预处理。 因此,加载器有点像其他构建工具中的“任务”,并提供了一种处理前端构建步骤的强大方法。 加载器可以将文件从不同的语言(如 TypeScript)转换为 JavaScript 或将内嵌图像加载为数据 URL。 加载器甚至允许你直接从你的 JavaScript 模块导入 CSS 文件!
来源: https : //webpack.js.org/concepts/loaders
问:什么是module.rules
?
module.rules
允许您在 webpack 配置中指定多个加载器。 这是显示加载器的简洁方式,有助于维护干净的代码。 它还为您提供每个加载器的完整概述。
来源: https : //webpack.js.org/concepts/loaders/#configuration
问:为什么我需要 webpack?
我主要使用 webpack 来丑化和缩小我的浏览器端代码,并将我所有的 JavaScript、CSS、Less 和图像文件合并到一个index.ntl
引用的bundle.js
文件中——这提高了性能和安全性(?)
另见文章:为什么使用 webpack
进一步阅读
https://babeljs.io/docs/en/usage
https://babeljs.io/docs/en/configuration
https://scotch.io/tutorials/javascript-transpilers-what-they-are-why-we-need-them
以下步骤已消除所有错误。
01)运行:
npm uninstall babel-core babel-cli babel-preset-env babel-preset-stage-0
02)运行:
npm install --save-dev @babel/core @babel/cli @babel/preset-env
按照官方文档:
https://babeljs.io/docs/en/usage#overview
03)在webpack.config.json
,改变这个:
module: {
rules: [{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ["env", "stage-0"]
}
}
},
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" }
]
},
{
test: /\.less$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{ loader: "less-loader" }
]
},
{
test: /\.jpg$/,
use: [
{ loader: "url-loader" }
]
},
{
test: require.resolve('jquery'),
use: [{
loader: 'expose-loader',
options: '$'
}]
},
{
test: require.resolve('js-cookie'),
use: [{
loader: 'expose-loader',
options: 'Cookies'
}]
},
{
test: require.resolve('he'),
use: [{
loader: 'expose-loader',
options: 'he'
}]
}
]
}
对此:
module: {
rules: [{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
},
{
test: /\.jpg$/,
use: ['url-loader']
},
{
test: require.resolve('jquery'),
loader: 'expose-loader',
options: {
exposes: ['$']
}
},
{
test: require.resolve('js-cookie'),
loader: 'expose-loader',
options: {
exposes: ['Cookies']
}
},
{
test: require.resolve('he'),
loader: 'expose-loader',
options: {
exposes: ['he']
}
}
]
}
以下是各种用法示例:
https://webpack.js.org/loaders
04)将.babelrc
重命名为.babelrc.json
并更改其内容:
{
"presets": [ [ "env", { "targets": { "node": "current" } } ] ]
}
对此:
{
"presets": ["@babel/preset-env"]
}
遵循这些示例:
https://babeljs.io/docs/en/configuration#babelrcjson
https://github.com/babel/example-node-server
并通过此答案告知:
https://stackoverflow.com/a/52435686
05)我的浏览器端文件common.js
中的几个导入语句导致错误,我更改了:
由此:
import getYear from 'date-fns/get_year';
import getMonth from 'date-fns/get_month';
import getDaysInMonth from 'date-fns/get_days_in_month';
import startOfMonth from 'date-fns/start_of_month';
import getDay from 'date-fns/get_day';
import format from 'date-fns/format';
对此:
import { getYear, getMonth, getDaysInMonth, startOfMonth, getDay, format} from 'date-fns';
由此:
import { saveAs } from 'file-saver/FileSaver';
对此:
import { saveAs } from 'file-saver';
由此:
import io from 'socket.io-client';
对此:
import { io } from 'socket.io-client'
/*
also had to do:
npm install socket.io-client
(and not just socket.io)
*/
由此:
import input_validator from './my_modules/input_validator';
对此:
import { input_validator } from './my_modules/input_validator';
/*
also had to change export from this:
module.exports = input_validator;
to this:
export { input_validator };
*/
06)为了摆脱less-loader
的错误,在webpack.config.js
,我改变了这个:
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
对此:
{
test: /\.less$/,
// use: ['style-loader', 'css-loader', 'less-loader']
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
},
{
loader: "less-loader",
options:
{
lessOptions:
{
math: "always",
},
},
}, ]
}
作为参考,仍然有弃用警告:
(node:22060) [DEP_WEBPACK_MAIN_TEMPLATE_HASH_FOR_CHUNK] DeprecationWarning: MainTemplate.hooks.hashForChunk is deprecated (use JavascriptModulesPlugin.getCompilationHooks().chunkHash instead)
(Use `node --trace-deprecation ...` to show where the warning was created)
(node:22060) [DEP_WEBPACK_CHUNK_TEMPLATE_HASH_FOR_CHUNK] DeprecationWarning: ChunkTemplate.hooks.hashForChunk is deprecated (use JavascriptModulesPlugin.getCompilationHooks().chunkHash instead)
(node:22060) [DEP_WEBPACK_COMPILATION_OPTIMIZE_CHUNK_ASSETS] DeprecationWarning: optimizeChunkAssets is deprecated (use Compilation.hooks.processAssets instead and use one of Compilation.PROCESS_ASSETS_STAGE_* as stage option)
(node:22060) [DEP_WEBPACK_DEPRECATION_ARRAY_TO_SET_LENGTH] DeprecationWarning: chunk.files was changed from Array to Set (using Array property 'length' is deprecated)
(node:22060) [DEP_WEBPACK_DEPRECATION_ARRAY_TO_SET_INDEXER] DeprecationWarning: chunk.files was changed from Array to Set (indexing Array is deprecated)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.