Add ESM localization documentation and working sample

Co-authored-by: hediet <2931520+hediet@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-09-11 15:57:07 +00:00
parent 74c8b62784
commit 4dc457ffe4
9 changed files with 1717 additions and 353 deletions

View file

@ -5,6 +5,7 @@
- [Option 2: Using plain webpack](#option-2-using-plain-webpack) - [Option 2: Using plain webpack](#option-2-using-plain-webpack)
- [Parcel](#using-parcel) - [Parcel](#using-parcel)
- [Vite](#using-vite) - [Vite](#using-vite)
- [Localization](#localization)
### Using webpack ### Using webpack
@ -227,3 +228,154 @@ monaco.editor.create(document.getElementById('container'), {
language: 'javascript' language: 'javascript'
}); });
``` ```
---
## Localization
Monaco Editor supports localization in multiple languages. When using the ESM version, you need to load the appropriate language files and configure the global NLS (National Language Support) variables.
### Available Languages
The monaco-editor package includes translations for the following languages:
- German (`de`)
- Spanish (`es`)
- French (`fr`)
- Italian (`it`)
- Japanese (`ja`)
- Korean (`ko`)
- Chinese Simplified (`zh-cn`)
- Chinese Traditional (`zh-tw`)
### Setting up Localization
To enable localization in your ESM integration, follow these steps:
1. **Import the language file** for your desired language before importing the editor:
```js
// Import the German localization
import 'monaco-editor/esm/nls.messages.de.js';
// Import monaco editor after the language file
import * as monaco from 'monaco-editor';
// Your existing MonacoEnvironment setup
self.MonacoEnvironment = {
getWorkerUrl: function (moduleId, label) {
// ... your worker configuration
}
};
// Create editor - it will now use German localization
monaco.editor.create(document.getElementById('container'), {
value: 'function x() {\n\tconsole.log("Hello world!");\n}',
language: 'javascript'
});
```
2. **For other languages**, replace the import with the appropriate file:
```js
// Spanish
import 'monaco-editor/esm/nls.messages.es.js';
// French
import 'monaco-editor/esm/nls.messages.fr.js';
// Italian
import 'monaco-editor/esm/nls.messages.it.js';
// Japanese
import 'monaco-editor/esm/nls.messages.ja.js';
// Korean
import 'monaco-editor/esm/nls.messages.ko.js';
// Chinese Simplified
import 'monaco-editor/esm/nls.messages.zh-cn.js';
// Chinese Traditional
import 'monaco-editor/esm/nls.messages.zh-tw.js';
```
### How it Works
The language files set up global variables that the editor uses for localization:
- `globalThis._VSCODE_NLS_MESSAGES` - Contains the translated strings
- `globalThis._VSCODE_NLS_LANGUAGE` - Contains the language code
When you import a language file, it automatically sets these global variables, and the editor will use the translated strings for its UI elements like context menus, command palette, error messages, etc.
### Dynamic Language Loading
You can also load languages dynamically based on user preferences:
```js
async function loadLanguage(language) {
if (language !== 'en') {
// Dynamically import the language file
await import(`monaco-editor/esm/nls.messages.${language}.js`);
}
// Import monaco after language is loaded
const monaco = await import('monaco-editor');
// Setup your editor
return monaco;
}
// Usage
loadLanguage('de').then((monaco) => {
monaco.editor.create(document.getElementById('container'), {
value: 'function x() {\n\tconsole.log("Hello world!");\n}',
language: 'javascript'
});
});
```
### Complete Example with Webpack
Here's a complete webpack example with German localization:
- `index.js`:
```js
// Import German localization first
import 'monaco-editor/esm/nls.messages.de.js';
import * as monaco from 'monaco-editor';
self.MonacoEnvironment = {
getWorkerUrl: function (moduleId, label) {
if (label === 'json') {
return './json.worker.bundle.js';
}
if (label === 'css' || label === 'scss' || label === 'less') {
return './css.worker.bundle.js';
}
if (label === 'html' || label === 'handlebars' || label === 'razor') {
return './html.worker.bundle.js';
}
if (label === 'typescript' || label === 'javascript') {
return './ts.worker.bundle.js';
}
return './editor.worker.bundle.js';
}
};
// Create editor with German UI
monaco.editor.create(document.getElementById('container'), {
value: ['function x() {', '\tconsole.log("Hello world!");', '}'].join('\n'),
language: 'javascript'
});
```
The webpack configuration remains the same as shown in the [plain webpack](#option-2-using-plain-webpack) section.
### Notes
- Language files must be imported **before** importing the main monaco-editor module
- If no language file is imported, the editor will use English (the default language)
- Language files are included in the monaco-editor package and don't require separate downloads
- The localization affects editor UI elements but does not translate your code content

1658
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -71,6 +71,7 @@
"vscode-languageserver-types": "3.17.5", "vscode-languageserver-types": "3.17.5",
"vscode-uri": "3.0.8", "vscode-uri": "3.0.8",
"webpack": "^5.76.0", "webpack": "^5.76.0",
"webpack-cli": "^6.0.1",
"yaserver": "^0.4.0" "yaserver": "^0.4.0"
}, },
"alias": { "alias": {

View file

@ -0,0 +1 @@
dist/

View file

@ -0,0 +1,75 @@
# Monaco Editor ESM Localization Sample
This sample demonstrates how to use localization with the Monaco Editor ESM version.
## Features
- Shows how to import language files before importing Monaco Editor
- Demonstrates German localization of the Monaco Editor UI
- Includes examples of localized context menus, command palette, and other UI elements
- Provides a reference for implementing other languages
## How to Run
1. Navigate to the root of the monaco-editor repository
2. Install dependencies: `npm install`
3. Build the sample: `cd samples/browser-esm-localized && npm run build`
4. Open `index.html` in your browser
## How it Works
The key to ESM localization is importing the language file **before** importing the main Monaco Editor module:
```javascript
// Import German localization first
import 'monaco-editor/esm/nls.messages.de.js';
// Then import Monaco Editor
import * as monaco from 'monaco-editor';
```
The language file sets up global variables that Monaco Editor uses for localization:
- `globalThis._VSCODE_NLS_MESSAGES` - Contains the translated strings
- `globalThis._VSCODE_NLS_LANGUAGE` - Contains the language code
## Testing Localization
Once the sample is running, you can test the localization by:
1. **Right-clicking** in the editor to see the German context menu
2. **Pressing F1** to open the command palette in German
3. **Using Ctrl+F** to open the search box with German labels
4. **Checking error messages** and tooltips in German
## Available Languages
The following language files are available:
- `nls.messages.de.js` - German
- `nls.messages.es.js` - Spanish
- `nls.messages.fr.js` - French
- `nls.messages.it.js` - Italian
- `nls.messages.ja.js` - Japanese
- `nls.messages.ko.js` - Korean
- `nls.messages.zh-cn.js` - Chinese Simplified
- `nls.messages.zh-tw.js` - Chinese Traditional
## Switching Languages
To test different languages, modify the import statement in `index.js`:
```javascript
// For French
import 'monaco-editor/esm/nls.messages.fr.js';
// For Spanish
import 'monaco-editor/esm/nls.messages.es.js';
// etc.
```
Then rebuild and reload the page.
## Dynamic Language Loading
For a more advanced implementation that loads languages dynamically, see the documentation in `docs/integrate-esm.md`.

View file

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Monaco Editor ESM Localization Sample</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.controls {
margin-bottom: 20px;
}
select,
button {
padding: 5px 10px;
margin-right: 10px;
}
#container {
width: 100%;
height: 600px;
border: 1px solid #ccc;
}
.info {
margin-top: 20px;
padding: 15px;
background-color: #f0f8ff;
border-left: 4px solid #0066cc;
}
</style>
</head>
<body>
<h2>Monaco Editor ESM Localization Sample</h2>
<div class="controls">
<label for="language-selector">Language:</label>
<select id="language-selector">
<option value="en">English</option>
<option value="de" selected>German (Deutsch)</option>
<option value="fr">French (Français)</option>
<option value="es">Spanish (Español)</option>
<option value="it">Italian (Italiano)</option>
<option value="ja">Japanese (日本語)</option>
<option value="ko">Korean (한국어)</option>
<option value="zh-cn">Chinese Simplified (简体中文)</option>
<option value="zh-tw">Chinese Traditional (繁體中文)</option>
</select>
<button id="reload-button">Apply Language</button>
</div>
<div id="container"></div>
<div class="info">
<h3>How to test localization:</h3>
<ul>
<li>Right-click in the editor to see the German context menu</li>
<li>Press F1 to open the command palette in German</li>
<li>Try using Ctrl+F to open the search box with German labels</li>
<li>
Select different languages from the dropdown and click "Apply Language" to reload with a
different localization
</li>
</ul>
<p>
<strong>Note:</strong> This demo shows German localization. To test other languages, you
would need to modify the import statement in index.js to import the corresponding language
file (e.g., 'monaco-editor/esm/nls.messages.fr.js' for French).
</p>
</div>
<script src="./app.bundle.js"></script>
</body>
</html>

View file

@ -0,0 +1,74 @@
// Import German localization before importing Monaco Editor
import '../../out/monaco-editor/esm/nls.messages.de.js';
import * as monaco from '../../out/monaco-editor/esm/vs/editor/editor.api.js';
self.MonacoEnvironment = {
getWorkerUrl: function (moduleId, label) {
if (label === 'json') {
return './json.worker.bundle.js';
}
if (label === 'css' || label === 'scss' || label === 'less') {
return './css.worker.bundle.js';
}
if (label === 'html' || label === 'handlebars' || label === 'razor') {
return './html.worker.bundle.js';
}
if (label === 'typescript' || label === 'javascript') {
return './ts.worker.bundle.js';
}
return './editor.worker.bundle.js';
}
};
// Language selector functionality
const languageSelector = document.getElementById('language-selector');
const reloadButton = document.getElementById('reload-button');
const editorContainer = document.getElementById('container');
// Function to reload the page with a different language
function loadLanguage(language) {
// Store the selected language in localStorage
localStorage.setItem('monaco-language', language);
// Reload the page to apply the new language
window.location.reload();
}
// Check if a different language was selected
const selectedLanguage = localStorage.getItem('monaco-language') || 'de';
languageSelector.value = selectedLanguage;
// If the current import doesn't match the selected language, we need to reload
const currentLanguage = 'de'; // This matches our import above
if (selectedLanguage !== currentLanguage) {
// For demonstration purposes, we'll show a message to reload manually
// In a real application, you would dynamically import the language
document.body.innerHTML = `
<h2>Monaco Editor ESM Localization Sample</h2>
<p>Please reload the page to apply the ${selectedLanguage} language setting.</p>
<button onclick="window.location.reload()">Reload Page</button>
`;
} else {
// Create the editor with German localization
languageSelector.addEventListener('change', (e) => {
loadLanguage(e.target.value);
});
reloadButton.addEventListener('click', () => {
loadLanguage(languageSelector.value);
});
monaco.editor.create(editorContainer, {
value: [
'function x() {',
'\t// This editor uses German localization',
'\t// Try right-clicking to see the German context menu',
'\t// Or press F1 to see the German command palette',
'\tconsole.log("Hallo Welt!");',
'}'
].join('\n'),
language: 'javascript',
theme: 'vs-dark',
minimap: { enabled: false }
});
}

View file

@ -0,0 +1,6 @@
{
"name": "browser-esm-localized",
"scripts": {
"build": "node ../../node_modules/webpack/bin/webpack.js --progress"
}
}

View file

@ -0,0 +1,30 @@
const path = require('path');
module.exports = {
mode: 'development',
entry: {
app: './index.js',
'editor.worker': '../../out/monaco-editor/esm/vs/editor/editor.worker.start.js',
'json.worker': '../../out/monaco-editor/esm/vs/language/json/json.worker.js',
'css.worker': '../../out/monaco-editor/esm/vs/language/css/css.worker.js',
'html.worker': '../../out/monaco-editor/esm/vs/language/html/html.worker.js',
'ts.worker': '../../out/monaco-editor/esm/vs/language/typescript/ts.worker.js'
},
output: {
globalObject: 'self',
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.ttf$/,
use: ['file-loader']
}
]
}
};