我正在使用Electron制作桌面应用,决定使用Monaco编辑器并使用npm install monaco-editor
进行安装,但运行应用程序时出现Cannot find module 'monaco-editor'
的错误。
我使用了electron-react-boilerplate
作为样板。
我尝试了使用ESM安装它的两种方法
这是我的package.json
文件:
{
"name": "electron-react-boilerplate",
"productName": "ElectronReact",
"version": "0.17.1",
"description": "Electron application boilerplate based on React, React Router, Webpack, React Hot Loader for rapid application development",
"scripts": {
"build": "concurrently \"yarn build-main\" \"yarn build-renderer\"",
"build-dll": "cross-env NODE_ENV=development webpack --config ./configs/webpack.config.renderer.dev.dll.babel.js --colors",
"build-e2e": "cross-env E2E_BUILD=true yarn build",
"build-main": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.main.prod.babel.js --colors",
"build-renderer": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.renderer.prod.babel.js --colors",
"dev": "cross-env START_HOT=1 node -r @babel/register ./internals/scripts/CheckPortInUse.js && cross-env START_HOT=1 yarn start-renderer-dev",
"flow": "flow",
"flow-typed": "rimraf flow-typed/npm && flow-typed install --overwrite || true",
"lint": "cross-env NODE_ENV=development eslint --cache --format=pretty .",
"lint-fix": "yarn --silent lint --fix; exit 0",
"lint-styles": "stylelint --ignore-path .eslintignore '**/*.*(css|scss)' --syntax scss",
"lint-styles-fix": "yarn --silent lint-styles --fix; exit 0",
"package": "yarn build && electron-builder build --publish never",
"package-all": "yarn build && electron-builder build -mwl",
"package-ci": "yarn postinstall && yarn build && electron-builder --publish always",
"package-linux": "yarn build && electron-builder build --linux",
"package-win": "yarn build && electron-builder build --win --x64",
"postinstall": "yarn flow-typed && electron-builder install-app-deps package.json && yarn build-dll && opencollective-postinstall",
"postlint-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{js,jsx,json,html,css,less,scss,yml}'",
"postlint-styles-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{css,scss}'",
"preinstall": "node ./internals/scripts/CheckYarn.js",
"prestart": "yarn build",
"start": "cross-env NODE_ENV=production electron ./app/main.prod.js",
"start-main-dev": "cross-env HOT=1 NODE_ENV=development electron -r @babel/register ./app/main.dev.js",
"start-renderer-dev": "cross-env NODE_ENV=development webpack-dev-server --config configs/webpack.config.renderer.dev.babel.js",
"test": "cross-env NODE_ENV=test BABEL_DISABLE_CACHE=1 jest",
"test-all": "yarn lint && yarn flow && yarn build && yarn test && yarn build-e2e && yarn test-e2e",
"test-e2e": "node -r @babel/register ./internals/scripts/CheckBuiltsExist.js && cross-env NODE_ENV=test testcafe electron:./ ./test/e2e/HomePage.e2e.js",
"test-e2e-live": "node -r @babel/register ./internals/scripts/CheckBuiltsExist.js && cross-env NODE_ENV=test testcafe-live electron:./ ./test/e2e/HomePage.e2e.js",
"test-watch": "yarn test --watch"
},
"lint-staged": {
"*.{js,jsx}": [
"cross-env NODE_ENV=development eslint --cache --format=pretty",
"git add"
],
"{*.json,.{babelrc,eslintrc,prettierrc,stylelintrc}}": [
"prettier --ignore-path .eslintignore --parser json --write",
"git add"
],
"*.{css,scss}": [
"stylelint --ignore-path .eslintignore --syntax scss --fix",
"prettier --ignore-path .eslintignore --single-quote --write",
"git add"
],
"*.{html,md,yml}": [
"prettier --ignore-path .eslintignore --single-quote --write",
"git add"
]
},
"main": "./app/main.prod.js",
"build": {
"productName": "ElectronReact",
"appId": "org.develar.ElectronReact",
"files": [
"app/dist/",
"app/app.html",
"app/main.prod.js",
"app/main.prod.js.map",
"package.json"
],
"dmg": {
"contents": [
{
"x": 130,
"y": 220
},
{
"x": 410,
"y": 220,
"type": "link",
"path": "/Applications"
}
]
},
"win": {
"target": [
"nsis",
"msi"
]
},
"linux": {
"target": [
"deb",
"rpm",
"snap",
"AppImage"
],
"category": "Development"
},
"directories": {
"buildResources": "resources",
"output": "release"
},
"publish": {
"provider": "github",
"owner": "electron-react-boilerplate",
"repo": "electron-react-boilerplate",
"private": false
}
},
"repository": {
"type": "git",
"url": "git+https://github.com/electron-react-boilerplate/electron-react-boilerplate.git"
},
"author": {
"name": "Electron React Boilerplate Maintainers",
"email": "electronreactboilerplate@gmail.com",
"url": "https://electron-react-boilerplate.js.org"
},
"contributors": [
{
"name": "Vikram Rangaraj",
"email": "vikr01@icloud.com",
"url": "https://github.com/vikr01"
},
{
"name": "Amila Welihinda",
"email": "amilajack@gmail.com",
"url": "https://github.com/amilajack"
}
],
"license": "MIT",
"bugs": {
"url": "https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues"
},
"keywords": [
"electron",
"boilerplate",
"react",
"redux",
"flow",
"sass",
"webpack",
"hot",
"reload"
],
"homepage": "https://github.com/electron-react-boilerplate/electron-react-boilerplate#readme",
"jest": {
"testURL": "http://localhost/",
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/internals/mocks/fileMock.js",
"\\.(css|less|sass|scss)$": "identity-obj-proxy"
},
"moduleFileExtensions": [
"js",
"jsx",
"json"
],
"transform": {
"^.+\\.jsx?$": "babel-jest"
},
"setupFiles": [
"./internals/scripts/CheckBuiltsExist.js"
]
},
"devDependencies": {
"@babel/core": "^7.4.0",
"@babel/plugin-proposal-class-properties": "^7.4.0",
"@babel/plugin-proposal-decorators": "^7.4.0",
"@babel/plugin-proposal-do-expressions": "^7.2.0",
"@babel/plugin-proposal-export-default-from": "^7.2.0",
"@babel/plugin-proposal-export-namespace-from": "^7.2.0",
"@babel/plugin-proposal-function-bind": "^7.2.0",
"@babel/plugin-proposal-function-sent": "^7.2.0",
"@babel/plugin-proposal-json-strings": "^7.2.0",
"@babel/plugin-proposal-logical-assignment-operators": "^7.2.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.2.0",
"@babel/plugin-proposal-numeric-separator": "^7.2.0",
"@babel/plugin-proposal-optional-chaining": "^7.2.0",
"@babel/plugin-proposal-pipeline-operator": "^7.3.2",
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-syntax-import-meta": "^7.2.0",
"@babel/plugin-transform-react-constant-elements": "^7.2.0",
"@babel/plugin-transform-react-inline-elements": "^7.2.0",
"@babel/preset-env": "^7.4.2",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@babel/register": "^7.4.0",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "^10.0.1",
"babel-jest": "^24.5.0",
"babel-loader": "^8.0.5",
"babel-plugin-dev-expression": "^0.2.1",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"chalk": "^2.4.2",
"concurrently": "^4.1.0",
"cross-env": "^5.2.0",
"cross-spawn": "^6.0.5",
"css-loader": "^3.1.0",
"detect-port": "^1.3.0",
"electron": "^4.1.3",
"electron-builder": "^20.39.0",
"electron-devtools-installer": "^2.2.4",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.11.2",
"enzyme-to-json": "^3.3.5",
"eslint": "^5.16.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-config-erb": "^0.0.2",
"eslint-config-prettier": "^4.1.0",
"eslint-formatter-pretty": "^2.1.1",
"eslint-import-resolver-webpack": "^0.11.0",
"eslint-plugin-compat": "^3.1.0",
"eslint-plugin-flowtype": "^3.4.2",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-jest": "^22.4.1",
"eslint-plugin-jsx-a11y": "6.2.1",
"eslint-plugin-prettier": "^3.0.1",
"eslint-plugin-promise": "^4.1.1",
"eslint-plugin-react": "^7.12.4",
"eslint-plugin-testcafe": "^0.2.1",
"fbjs-scripts": "^1.2.0",
"file-loader": "^3.0.1",
"flow-bin": "^0.95.1",
"flow-runtime": "^0.17.0",
"flow-typed": "^2.5.1",
"husky": "^1.3.1",
"identity-obj-proxy": "^3.0.0",
"jest": "^24.5.0",
"lint-staged": "^8.1.5",
"mini-css-extract-plugin": "^0.5.0",
"node-sass": "^4.11.0",
"opencollective-postinstall": "^2.0.2",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"prettier": "^1.16.4",
"react-test-renderer": "^16.8.6",
"redux-logger": "^3.0.6",
"rimraf": "^2.6.3",
"sass-loader": "^7.1.0",
"sinon": "^7.3.1",
"spectron": "^5.0.0",
"style-loader": "^0.23.1",
"stylelint": "^9.10.1",
"stylelint-config-prettier": "^5.0.0",
"stylelint-config-standard": "^18.2.0",
"terser-webpack-plugin": "^1.2.3",
"testcafe": "^1.1.0",
"testcafe-browser-provider-electron": "^0.0.8",
"testcafe-live": "^0.1.4",
"testcafe-react-selectors": "^3.1.0",
"url-loader": "^1.1.2",
"webpack": "^4.29.6",
"webpack-bundle-analyzer": "^3.1.0",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.2.1",
"webpack-merge": "^4.2.1",
"yarn": "^1.15.2"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^5.8.1",
"@material-ui/core": "^4.2.1",
"@material-ui/icons": "^4.2.1",
"axios": "^0.19.0",
"classnames": "^2.2.6",
"connected-react-router": "^6.3.2",
"core-js": "2",
"devtron": "^1.4.0",
"electron-debug": "^2.1.0",
"electron-log": "^3.0.4",
"electron-store": "^4.0.0",
"electron-updater": "^4.0.6",
"history": "^4.9.0",
"monaco-editor": "^0.19.2",
"monaco-editor-webpack-plugin": "^1.8.2",
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-copy-to-clipboard": "^5.0.1",
"react-dom": "^16.8.6",
"react-hot-loader": "^4.8.2",
"react-panelgroup": "^1.0.7",
"react-redux": "^6.0.1",
"react-resize-observer": "^1.1.1",
"react-router": "^5.0.0",
"react-router-dom": "^5.0.0",
"react-simple-resizer": "^1.3.1",
"react-tabs": "^3.1.0",
"react-virtualized-auto-sizer": "^1.0.2",
"react-window": "^1.8.5",
"redux": "^4.0.1",
"redux-promise-middleware": "^6.1.1",
"redux-thunk": "^2.3.0",
"shell-quote": "^1.7.2",
"source-map-support": "^0.5.11",
"ssh2": "^0.8.5",
"xterm": "^3.14.5"
},
"devEngines": {
"node": ">=7.x",
"npm": ">=4.x",
"yarn": ">=0.21.3"
},
"collective": {
"url": "https://opencollective.com/electron-react-boilerplate-594"
},
"browserslist": "electron 1.6"
}
我尝试使用不同版本的monaco-editor
和monaco-editor-webpack-plugin
,但没有成功,这是在这里建议的。
这是我的Webpack配置,electron-react-boilerplate
的Webpack配置有点混乱,可能是出错的地方,这里提供了一个链接,其中包含了electron-react-boilerplate
所使用的Webpack配置文件,我只修改了那个文件。
/**
* Base webpack config used across other specific configs
*/
import path from 'path';
import webpack from 'webpack';
import { dependencies } from '../package.json';
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
export default {
externals: [...Object.keys(dependencies || {})],
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
loader: 'ts-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
// entry: {
// // "app": './index.js',
// // Package each language's worker and give these filenames in `getWorkerUrl`
// "editor.worker": 'node_modules/monaco-editor/esm/vs/editor/editor.worker.js',
// "json.worker": 'node_modules/monaco-editor/esm/vs/language/json/json.worker',
// "css.worker": 'node_modules/monaco-editor/esm/vs/language/css/css.worker',
// "html.worker": 'node_modules/monaco-editor/esm/vs/language/html/html.worker',
// "ts.worker": 'node_modules/monaco-editor/esm/vs/language/typescript/ts.worker',
// },
output: {
path: path.join(__dirname, '..', 'app'),
// https://github.com/webpack/webpack/issues/1114
libraryTarget: 'commonjs2'
},
/**
* Determine the array of extensions that should be used to resolve modules.
*/
resolve: {
extensions: ['.js', '.tsx', '.ts', '.jsx', '.json']
},
plugins: [
new webpack.EnvironmentPlugin({
NODE_ENV: 'production'
}),
new MonacoWebpackPlugin(),
new webpack.NamedModulesPlugin()
]
};
为了完整起见,我这样导入Monaco编辑器:import * as Monaco from 'monaco-editor'
。如果我使用import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
,它可以工作,但没有我需要的大多数功能。
node_modules/monaco-editor/esm/vs/editor/editor.api.js
解决了我的问题。 - brk