์์
์๋ฅผ๋ก๋ ํ ์ ์์ต๋๋ค. JSON ๊ตฌ๋ฌธ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ์๋ํ์ง ์์ต๋๋ค. ๋ธ๋ผ์ฐ์ ์ฝ์์ Could not load worker
๊ฒฝ๊ณ ๊ฐ ํ์๋ฉ๋๋ค.
๋ํ json ์์ปค ๊ฐ์ ธ ์ค๊ธฐ๋ฅผ ์๋ํ์ต๋๋ค.
import "ace-builds/src-noconflict/worker-json";
์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
TypeError: Cannot read property 'window' of undefined
import React from "react";
import ReactDOM from "react-dom";
import AceEditor from "react-ace";
import "ace-builds/src-noconflict/ace";
import "ace-builds/src-noconflict/mode-json";
import "ace-builds/src-noconflict/theme-github";
let text =
'{\n "id": 0,\n ' +
'"script": """\n function add(x, y) {\n return x + y;\n }\n add(1, 2);\n """' +
',\n "descr": "add two numbers"\n}';
function App() {
return (
<div className="App">
<h1>Code Editor Demo</h1>
<AceEditor
mode="json"
theme="github"
onChange={(value, stat) => {
console.log("onChange", value, stat);
}}
value={text}
name="UNIQUE_ID_OF_DIV"
editorProps={{ $blockScrolling: true }}
/>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Codesandbox https://codesandbox.io/embed/ace-worker-3-vrr68
CSS์ ๋น์ทํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ฌ ๋ธ๋ผ์ฐ์ ์ฝ์์์ ๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:9000/settings/landing-page/worker-css.js' failed to load.
์์ ์๋ฅผ ์ง์ ๊ฐ์ ธ ์ค๋ ค๊ณ ํ ๋
import 'ace-builds/src-noconflict/worker-css';
๋ด ๋น๋๊ฐ ์คํจํ์ต๋๋ค.
ERROR in ../node_modules/ace-builds/src-noconflict/worker-css.js
Module not found: Error: Can't resolve 'ace/lib/es5-shim' in 'path/to/node_modules/ace-builds/src-noconflict'
webpack-resolver๋ฅผ ํฌํจํด์ผํฉ๋๋ค.
import "ace-builds/webpack-resolver";
๋๋ ๊ฐ ๋ชจ๋์ ๋ํ URL์ ๋ณ๋๋ก ๊ตฌ์ฑํ์ญ์์ค.
import jsonWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-json";
ace.config.setModuleUrl("ace/mode/json_worker", jsonWorkerUrl)
import cssWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-css";
ace.config.setModuleUrl("ace/mode/css_worker", cssWorkerUrl)
๋ ๋ฐฉ๋ฒ ๋ชจ๋ "ํ์ผ ๋ก๋"๊ฐ ํ์ํฉ๋๋ค.
๋ํ react-ace๋ ace๊ฐ ์์ง ์ํฌํธ๋์ง ์์ ๊ฒฝ์ฐ brace๋ฅผ๋ก๋ํ๋ ค๊ณ ํ๋ฏ๋ก react-ace ์ ์ ace-build๋ฅผ ์ํฌํธํด์ผํฉ๋๋ค.
import "ace-builds";
import AceEditor from "react-ace";
๊ทธ ์ํ์ @nightwingํ์ง๋ง ์์
ace-builds
ํ๊ธฐ ์ ์ react-ace
๋๋ฅผ ์ํด ํ์ด์ด ํญ์ค์ ์คํจํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ์ ํจ๊ป ์ผํ๋ค.
import AceEditor from 'react-ace';
import 'ace-builds/webpack-resolver';
// then the mode, theme & extension
import 'ace-builds/src-noconflict/mode-json';
import 'ace-builds/src-noconflict/theme-tomorrow_night';
import 'ace-builds/src-noconflict/ext-searchbox';
๊ทธ๋ฌ๋ ๋ด ํ
์คํธ์ ํจ๊ป ์๋ํ์ง ๋ชปํ์ต๋๋ค. webpack-resolver
๊ฐ์ ธ ์ค๊ธฐ ์ค์ ๋ค์ ํ
์คํธ์์ ์คํจํฉ๋๋ค.
TypeError: Cannot read property 'setModuleUrl' of undefined
๋๋ ๋ค์๊ณผ ๊ฐ์ ๋ชจ์ ์์ด์ค๊ฐ ํ์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
global.ace = require('ace-builds/src-min-noconflict/ace');
๋๊ตฌ๋ ์ง create-react-app์ผ๋ก์ด ์์ ์ ํ์ต๋๊น? ๋ด๊ฐ ์ถ๊ฐํ๋ฉด ๋ด ์ปดํ์ผ์ด ์์ํ ์ค๋จ๋ฉ๋๋ค.
import 'ace-builds/webpack-resolver';
๋ชจ๋์ ์ง์ ๊ฐ์ ธ ์ค๋ ๊ฒฝ์ฐ useWorker: false
๋ฅผ setOptions์ ์ถ๊ฐํ์ฌ ์์ ํ์ต๋๋ค. ์ด๊ฒ์ด ์ข์ ํด๊ฒฐ์ฑ
์ด๋ผ๋ฉด ๋ญ๊ฐ ๋น ์ง ๊ฒ์ด ์๋ค๋ฉด README.md
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ์ ์
๋ฐ์ดํธํด์ผํฉ๋๋ค.
@khoomeister ๋ ๋ชจ๋ ๊ฒฝ๊ณ ๋ฅผ ์ ๊ฑฐํ์ง๋ง ์ฑ๋ฅ์ด ๋์ ๋๊ฒ ๋๋น ์ก์ต๋๊น (๊ทธ๋ฅ ๋ด ๊ตฌํ ์ผ ์ ์์)?
(ํ btw์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค!)
setOptions={{
useWorker: false
}}
๋๋ฅผ ์ํด ์๋ํฉ๋๋ค. ๊ฐ์ฌํฉ๋๋ค @khoomeister
๋ํ ์ฌ์ ํ์ด ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
"useWorker๋ฅผ ์ฌ์ฉํ๋ฉด ๋จ์ ์ด ์์ต๋๊น? ๊ทธ ์์
์๋ค์ ์ ํํ ๋ฌด์์ํฉ๋๊น?
create-react-app ํ๋ก์ ํธ๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
๋ด๊ฐํด์ผ ํ ์ ์ผํ ์ผ์ ๋ด App.tsx์ ์ด๊ฒ์ ์ถ๊ฐํ๋ ๊ฒ์ ๋๋ค.
import 'ace-builds/webpack-resolver'
useWorker๋ฅผ false๋ก ์ค์ ํ๋ฉด ์ ์ด๋ ๋ค๋ฅธ ๊ฒ๋ค์ ๊ตฌ๋ฌธ ๊ฒ์ฌ๊ฐ ๋นํ์ฑํ๋๋ฏ๋ก ์ฌ์ฉํ๊ณ ์ถ์ง ์์์ต๋๋ค.
์์ arjunu์ ์๊ฒฌ์ ๋ฐ๋ผ ํ ์คํธ์ ํจ๊ป ์๋ํ๋๋ก ์ด๊ฒ์ด ์ถฉ๋ถํ ์ข์์ง ์์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
๋ด create-react-app ํ๋ก์ ํธ์ webpack-resolver๋ฅผ ์ถ๊ฐํ๋ฉด ์ปดํ์ผ ์๊ฐ์ด ์์ฒญ๋๊ฒ ์ฆ๊ฐํ๊ณ ๋น๋ ๋๋ ํ ๋ฆฌ์ ์๋ฐฑ ๊ฐ์ ํ์ผ์ด ์ถ๊ฐ๋ฉ๋๋ค. ๊ตฌ์ฑํ๋ ace-build์ ๊ฐ ๋ชจ๋์ ๋ํด ํ๋์ฉ ๊ฐ์ ํฉ๋๋ค. ๊ทธ๋๋ ํ์ํ ๋ชจ๋์ ๋ํ URL ๊ตฌ์ฑ์ ์ ์๋ํฉ๋๋ค.
์ด๊ฒ์ react-ace๊ฐ ์๋ react-scripts ๋๋ ace-builds์ ๋ฌธ์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
์ง๊ธ๊น์ง react-ace
์ ๋ง์กฑํฉ๋๋ค. ์ด์ฌํ ์ผํด ์ฃผ์ ๋ชจ๋ ๋ถ๋ค๊ป ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
๋ฒ์ 8๋ก ์
๊ทธ๋ ์ด๋ํ๋ ค๊ณ ํ์ง๋ง worker
๋ฌธ์ ๋ก ์ธํด ์คํจ ํ์ผ๋ฏ๋ก ์ง๊ธ์ 7์ ๋จธ๋ฌผ๊ณ ์์ต๋๋ค.
"react-scripts": "3.2.0"
(๋ฆฌ ์กํธ ์ฑ ๋ง๋ค๊ธฐ)๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
์์ ์๋ฅผ๋ก๋ ํ ์ ์์ผ๋ฉฐ ์ฝ์์ ๋ค์ ์ค๋ฅ๊ฐ ํ์๋์์ต๋๋ค.
03226918-0f44-4ac8-b073-1abc2ed64713:1 Refused to execute script from 'http://localhost:8000/worker-javascript.js' because its MIME type ('text/html') is not executable.
(anonymous) @ 03226918-0f44-4ac8-b073-1abc2ed64713:1
9297f3cf-c75b-4245-8c37-3ac2a7fed94d:1 Refused to execute script from 'http://localhost:8000/worker-javascript.js' because its MIME type ('text/html') is not executable.
(anonymous) @ 9297f3cf-c75b-4245-8c37-3ac2a7fed94d:1
03226918-0f44-4ac8-b073-1abc2ed64713:1 Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:8000/worker-javascript.js' failed to load.
at blob:http://localhost:8000/03226918-0f44-4ac8-b073-1abc2ed64713:1:1
(anonymous) @ 03226918-0f44-4ac8-b073-1abc2ed64713:1
9297f3cf-c75b-4245-8c37-3ac2a7fed94d:1 Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:8000/worker-javascript.js' failed to load.
at blob:http://localhost:8000/9297f3cf-c75b-4245-8c37-3ac2a7fed94d:1:1
(anonymous) @ 9297f3cf-c75b-4245-8c37-3ac2a7fed94d:1
์์
์๋ฅผ ๋นํ์ฑํํ๋ ๊ฒ์ ๋์๊ฒ ์ต์
์ด ์๋๋๋ค. import 'ace-builds/webpack-resolver';
์ฌ์ฉํ์ฌ webpack-resolver๋ฅผ ์ถ๊ฐํ๋ ค๊ณ ํ์ง๋ง ์ฑ์ด ์ปดํ์ผ๋์ง ์์์ต๋๋ค. ์ปดํ์ผ์ด ๋ฌด๊ธฐํ ์ค๋จ๋์์ต๋๋ค.
๋ํ file-loader
๋ฐ setModuleUrl
์ฌ์ฉํ์ฌ ์๋์ผ๋ก ์ถ๊ฐํ๋ ค๊ณ ์๋ํ์ง๋ง ace/lib/es5-shim
๋๋ฝ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
์ด ๋ฌธ์ ๋ # 733 # 755 ๋ฐ ajaxorg / ace-builds # 161๊ณผ ๊ด๋ จ๋ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค.
@mattjstar ํจ๊ป ์์ ํ์ต๋๋ค.
import 'ace-builds'
import 'ace-builds/webpack-resolver'
๋ฐ๋ผ์ ๋ฆฌ์กธ๋ฒ ์ ์ ace-builds
๋ฅผ ๊ฐ์ ธ์ต๋๋ค (AceEditor์ ๊ด๋ จ๋ ๋ค๋ฅธ ๋ชจ๋ ๊ฒ).
์์ @arjunu ๋ต๋ณ์ ์ฐธ์กฐํ์ญ์์ค.
javascript-worker๋ฅผ ์ถ๊ฐํ๊ธฐ ์ํด ๋ง์ง๋ง 3 ์ค์ ์ถ๊ฐํ์ต๋๋ค.
import AceEditor from "react-ace";
import "ace-builds/src-min-noconflict/mode-javascript";
import "ace-builds/src-min-noconflict/theme-tomorrow_night_eighties";
import "ace-builds/src-min-noconflict/ext-language_tools";
import "ace-builds/src-min-noconflict/ext-spellcheck";
import "ace-builds/src-min-noconflict/snippets/javascript";
import 'ace-builds/src-min-noconflict/ext-searchbox';
const ace = require('ace-builds/src-noconflict/ace');
ace.config.set("basePath", "https://cdn.jsdelivr.net/npm/[email protected]/src-noconflict/");
ace.config.setModuleUrl('ace/mode/javascript_worker', "https://cdn.jsdelivr.net/npm/[email protected]/src-noconflict/worker-javascript.js");
cdn.jsdelivr.net์ ์์กดํ์ง ์์ผ๋ ค๋ฉด ๋ก์ปฌ ํ๊ฒฝ์์ worker-javascript.js ํ์ผ์ ๋ณต์ฌ / ๋ถ์ฌ ๋ฃ๊ธฐ ํ ์ ์์ต๋๋ค.
webpack-resolver๋ฅผ ํฌํจํด์ผํฉ๋๋ค.
import "ace-builds/webpack-resolver";
๋๋ ๊ฐ ๋ชจ๋์ ๋ํ URL์ ๋ณ๋๋ก ๊ตฌ์ฑํ์ญ์์ค.
import jsonWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-json"; ace.config.setModuleUrl("ace/mode/json_worker", jsonWorkerUrl)
import cssWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-css"; ace.config.setModuleUrl("ace/mode/css_worker", cssWorkerUrl)
๋ ๋ฐฉ๋ฒ ๋ชจ๋ "ํ์ผ ๋ก๋"๊ฐ ํ์ํฉ๋๋ค.
๋ํ react-ace๋ ace๊ฐ ์์ง ์ํฌํธ๋์ง ์์ ๊ฒฝ์ฐ brace๋ฅผ๋ก๋ํ๋ ค๊ณ ํ๋ฏ๋ก react-ace ์ ์ ace-build๋ฅผ ์ํฌํธํด์ผํฉ๋๋ค.
import "ace-builds"; import AceEditor from "react-ace";
์ด๊ฒ์ ์๋ฒฝํ๊ฒ ์๋ํฉ๋๋ค. ๋ชจ๋ ๋๋ ํ ๋ง๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ์์ ์ URL ์ ์
import "ace-builds"
import ACE from "react-ace/dist/react-ace.min";
import jsonWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-json";
ace.config.setModuleUrl("ace/mode/json_worker", jsonWorkerUrl);
import xmlWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-xml";
ace.config.setModuleUrl("ace/mode/xml_worker", xmlWorkerUrl);
import jsWorkerUrl from "file-loader!ace-builds/src-noconflict/worker-javascript";
ace.config.setModuleUrl("ace/mode/javascript_worker", jsWorkerUrl);
import "ace-builds/src-min-noconflict/mode-typescript";
import "ace-builds/src-min-noconflict/mode-javascript";
import "ace-builds/src-min-noconflict/mode-graphqlschema";
import "ace-builds/src-min-noconflict/mode-json";
import "ace-builds/src-min-noconflict/mode-xml";
import "ace-builds/src-min-noconflict/mode-markdown";
import "ace-builds/src-min-noconflict/mode-html";
import "ace-builds/src-min-noconflict/theme-github";
import "ace-builds/src-min-noconflict/theme-tomorrow";
import "ace-builds/src-min-noconflict/theme-kuroir";
import "ace-builds/src-min-noconflict/ext-searchbox";
๋ํ ์ค์ ํ ํ์ ์์ : setOptions={{ useWorker: false }}
https://github.com/securingsincity/react-ace/issues/725#issuecomment -546711308
ace-builds/src-.../
ํด๋์์๋ ์ปค์คํ
์์
์๋ฅผ ์ํ๋ฉด ์ด๋ป๊ฒํ๋์?
๋ด๊ฐ ๋ง๋ ANTLR ํ์์ ํจ๊ป ์ฌ์ฉํด์ผํฉ๋๋ค.
์ ์ฒด [email protected]
ํตํฉ์ ์ฌ๊ธฐ์ ๋ก๋๋ค.
import dynamic from "next/dynamic";
const AceEditor = dynamic(
async () => {
const reactAce = await import("react-ace");
// prevent warning in console about misspelled props name.
await import("ace-builds/src-min-noconflict/ext-language_tools");
// import your theme/mode here. <AceEditor mode="javascript" theme="solarized_dark" />
await import("ace-builds/src-min-noconflict/mode-javascript");
await import("ace-builds/src-min-noconflict/theme-solarized_dark");
// as <strong i="7">@Holgrabus</strong> commented you can paste these file into your /public folder.
// You will have to set basePath and setModuleUrl accordingly.
let ace = require("ace-builds/src-min-noconflict/ace");
ace.config.set(
"basePath",
"https://cdn.jsdelivr.net/npm/[email protected]/src-noconflict/"
);
ace.config.setModuleUrl(
"ace/mode/javascript_worker",
"https://cdn.jsdelivr.net/npm/[email protected]/src-noconflict/worker-javascript.js"
);
return reactAce;
},
{
ssr: false // react-ace doesn't support server side rendering as it uses the window object.
}
);
export default () => <AceEditor mode="javascript" theme="solarized_dark" />
@ jan-osch ์๋ฅผ ๋ค์ด "customWorker.js"๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ace.config.setModuleUrl("ace/mode/myWorker", "/customWorker.js")
ํด์ผํฉ๋๊น? (/ public ํด๋์ customWorker.js ๋ฃ๊ธฐ)
Typescript์์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ ค๋ฉด ๋ค์์ ์ํํ์ฌ ace ๊ตฌ์ฑ์ ์ค์ ํด์ผํฉ๋๋ค.
import { config } from 'ace-builds';
config.set(
"basePath",
"https://cdn.jsdelivr.net/npm/[email protected]/src-noconflict/"
);
config.setModuleUrl(
"ace/mode/javascript_worker",
"https://cdn.jsdelivr.net/npm/[email protected]/src-noconflict/worker-javascript.js"
);
Webpack์ ๋ค์ ํ ์คํธ๋ฅผ ์ถ๊ฐํ์ต๋๋ค.
module: {
rules: [
{
test: /ace-builds.*\/worker-.*$/,
loader: 'file-loader',
options: {
esModule: false,
name: '[name].[hash:8].[ext]',
},
},
],
},
๊ทธ๋ฐ ๋ค์ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
import ace from 'ace-builds/src-noconflict/ace';
import cssWorkerUrl from 'ace-builds/src-noconflict/worker-css';
ace.config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl);
@pranavwani ์์ ์ ์ํ๋๋ก ๊ฐ์ ธ
Cannot read property 'Range' of undefined. "Error loading module."
ace.tsx
๊ฐ ace / range๋ฅผ ๊ฐ์ ธ ์ค๋ ค๊ณ ํ ๋ Cannot read property 'Range' of undefined. "Error loading module."
.
๋ฌธ์ ๋ window.ace
๊ฐ ์ ์ ๋์๊ธฐ ๋๋ฌธ์ ace-builds๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ง๋ง ace๊ฐ editorOptions์ ace.acequire ๊ตฌ๋ฌธ์ ๊ณ์ ์ฌ์ฉํ๋ค๋ ๊ฒ ์
๋๋ค. ์ด ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฐพ์ ์ฌ๋์ด ์์ต๋๊น?
Webpack์ ๋ค์ ํ ์คํธ๋ฅผ ์ถ๊ฐํ์ต๋๋ค.
module: { rules: [ { test: /ace-builds.*\/worker-.*$/, loader: 'file-loader', options: { esModule: false, name: '[name].[hash:8].[ext]', }, }, ], },
๊ทธ๋ฐ ๋ค์ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
import ace from 'ace-builds/src-noconflict/ace'; import cssWorkerUrl from 'ace-builds/src-noconflict/worker-css'; ace.config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl);
webpack ๊ตฌ์ฑ์ ์์ ํ์ง ์๊ณ ๋ ์ํ ํ ์ ์์ต๋๋ค.
import ace from 'ace-builds/src-noconflict/ace';
/* eslint import/no-webpack-loader-syntax: off */
import cssWorkerUrl from 'ace-builds/src-noconflict/worker-css';
ace.config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl);
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
webpack-resolver๋ฅผ ํฌํจํด์ผํฉ๋๋ค.
๋๋ ๊ฐ ๋ชจ๋์ ๋ํ URL์ ๋ณ๋๋ก ๊ตฌ์ฑํ์ญ์์ค.
๋ ๋ฐฉ๋ฒ ๋ชจ๋ "ํ์ผ ๋ก๋"๊ฐ ํ์ํฉ๋๋ค.
๋ํ react-ace๋ ace๊ฐ ์์ง ์ํฌํธ๋์ง ์์ ๊ฒฝ์ฐ brace๋ฅผ๋ก๋ํ๋ ค๊ณ ํ๋ฏ๋ก react-ace ์ ์ ace-build๋ฅผ ์ํฌํธํด์ผํฉ๋๋ค.