mirror of
https://github.com/microsoft/vscode-extension-samples.git
synced 2026-06-13 07:10:26 +08:00
Restructure the code to fit to latest nls tooling
This commit is contained in:
1
i18n-sample/.gitignore
vendored
1
i18n-sample/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
out
|
||||
node_modules
|
||||
package.nls.*.json
|
||||
|
||||
53
i18n-sample/.vscode/tasks.json
vendored
53
i18n-sample/.vscode/tasks.json
vendored
@ -1,30 +1,27 @@
|
||||
// Available variables which can be used inside of strings.
|
||||
// ${workspaceRoot}: the root folder of the team
|
||||
// ${file}: the current opened file
|
||||
// ${fileBasename}: the current opened file's basename
|
||||
// ${fileDirname}: the current opened file's dirname
|
||||
// ${fileExtname}: the current opened file's extension
|
||||
// ${cwd}: the current working directory of the spawned process
|
||||
|
||||
// A task runner that calls a custom npm script that compiles the extension.
|
||||
{
|
||||
"version": "0.1.0",
|
||||
|
||||
// we want to run npm
|
||||
"command": "npm",
|
||||
|
||||
// the command is a shell script
|
||||
"isShellCommand": true,
|
||||
|
||||
// show the output window only if unrecognized errors occur.
|
||||
"showOutput": "silent",
|
||||
|
||||
// we run the custom script "compile" as defined in package.json
|
||||
"args": ["run", "compile", "--loglevel", "silent"],
|
||||
|
||||
// The tsc compiler is started in watching mode
|
||||
"isBackground": true,
|
||||
|
||||
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
|
||||
"problemMatcher": "$tsc-watch"
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"isBackground": true,
|
||||
"problemMatcher": [
|
||||
"$tsc-watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "gulp",
|
||||
"task": "clean",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"type": "gulp",
|
||||
"task": "build",
|
||||
"problemMatcher": [
|
||||
"$tsc"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -9,31 +9,20 @@ it shows two commands: Hello and Bye in English and Japanese.
|
||||
**Assumptions**
|
||||
|
||||
* All localization files are under the i18n folder.
|
||||
* You could have created this folder by hand, or you could have used the
|
||||
`vscode-nls-dev` tool to extract it.
|
||||
* Under the i18n folder, you have sub-folders that represent the language you
|
||||
want to localize. These names follow the ISO 639-3 convention.
|
||||
* Under the language names folder you will create json files that mirror the
|
||||
structure of the source code for your extension (e.g., out/src). The json
|
||||
files are key:value pairs of the text that you want to localize. The naming
|
||||
convention is `<file_name>.i18n.json`.
|
||||
* If you have a top-level package.nls.json file in your extension, you should
|
||||
have one for each language following the naming convention of
|
||||
`package.i18n.json`.
|
||||
* You could have created this folder by hand, or you could have used the `vscode-nls-dev` tool to extract it.
|
||||
* Under the i18n folder, you have sub-folders that represent the language you want to localize. These names follow the ISO 639-3 convention.
|
||||
* Under the language names folder you will create json files that mirror the structure of the source code for your extension (e.g., out/src). The json files are key:value pairs of the text that you want to localize. The naming convention is `<file_name>.i18n.json`.
|
||||
* If you have a top-level package.nls.json file in your extension, you should have one for each language following the naming convention of `package.i18n.json`.
|
||||
|
||||
# How to run locally
|
||||
|
||||
Localization values are only applied in the VSIX package.
|
||||
Localization values are only applied when running the gulp `build` task. During normally development which uses `tsc -watch` to compile no localization post processing happends. This speeds up development time.
|
||||
|
||||
1. Ensure that you have `gulp-cli` installed globally using `npm install
|
||||
--global gulp-cli`.
|
||||
1. Ensure that you have `gulp-cli` installed globally using `npm install --global gulp-cli`.
|
||||
1. Run `npm install` to bring in the dependencies.
|
||||
1. Follow the steps at
|
||||
https://code.visualstudio.com/docs/extensions/publish-extension to ensure
|
||||
that you have installed vsce and have a publisher account.
|
||||
1. Follow the steps at https://code.visualstudio.com/docs/extensions/publish-extension to ensure that you have installed vsce and have a publisher account.
|
||||
1. Run `vsce package` to produce a .vsix file.
|
||||
1. Install the .vsix file following the instructions at
|
||||
https://code.visualstudio.com/docs/editor/extension-gallery#_install-from-a-vsix
|
||||
1. Install the .vsix file following the instructions at https://code.visualstudio.com/docs/editor/extension-gallery#_install-from-a-vsix
|
||||
1. Change your locale to Japanese by invoking "Configure Language" from the Command Palette.
|
||||
|
||||
See the demo.gif file in this repository for a screencast.
|
||||
@ -41,18 +30,14 @@ See the demo.gif file in this repository for a screencast.
|
||||
# What happens behind the scenes
|
||||
|
||||
1. The `vscode-nls-dev` module is used to rewrite the generated JavaScript.
|
||||
1. Calls of the form `localize('some_key', 'Hello')` are transformed to
|
||||
`localize(0, null)` where the first parameter (0, in this example) is the
|
||||
position of the key in your messages file.
|
||||
1. The contents of the i18n folder are transformed from key:value pairs into
|
||||
positional arrays.
|
||||
1. Calls of the form `localize('some_key', 'Hello')` are transformed to `localize(0, null)` where the first parameter (0, in this example) is the position of the key in your messages file.
|
||||
1. The contents of the i18n folder are transformed from key:value pairs into positional arrays.
|
||||
|
||||
# Considerations
|
||||
|
||||
It is possible to use your own localization pipeline.
|
||||
|
||||
1. Localizations in your package.json can be done by wrapping the localized text
|
||||
in the form %some.key%.
|
||||
1. Localizations in your package.json can be done by wrapping the localized text in the form %some.key%.
|
||||
|
||||
```
|
||||
// [Before] package.json
|
||||
@ -85,11 +70,7 @@ It is possible to use your own localization pipeline.
|
||||
|
||||
Then, create the corresponding package.nls.{your_language}.json files for each language to localize.
|
||||
|
||||
2. It is also possible to use your own library for localizing text in your
|
||||
source file. You would use the value of `process.env.VSCODE_NLS_CONFIG`
|
||||
environment variable. At runtime, this environment variable is a JSON string
|
||||
that contains the locale that VS Code is run with. For instance, this is the
|
||||
value for Japanese: `"{"locale":"ja","availableLanguages":{"*":"ja"}}"`
|
||||
2. It is also possible to use your own library for localizing text in your source file. You would use the value of `process.env.VSCODE_NLS_CONFIG` environment variable. At runtime, this environment variable is a JSON string that contains the locale that VS Code is run with. For instance, this is the value for Japanese: `"{"locale":"ja","availableLanguages":{"*":"ja"}}"`
|
||||
|
||||
```JavaScript
|
||||
|
||||
@ -110,10 +91,8 @@ localize(config);
|
||||
|
||||
## 0.0.2
|
||||
|
||||
Hook up the vscode-nls-dev functions to gulp so that you can just run `vsce
|
||||
package` without manual transformations.
|
||||
Hook up the vscode-nls-dev functions to gulp so that you can just run `vsce package` without manual transformations.
|
||||
|
||||
## 0.0.1:
|
||||
|
||||
Manually transform the calls to localize to illustrate explicitly what is going
|
||||
on.
|
||||
Manually transform the calls to localize to illustrate explicitly what is going on.
|
||||
@ -1,116 +1,93 @@
|
||||
// This is based off https://github.com/Microsoft/vscode/blob/master/build/gulpfile.extensions.js
|
||||
// but simplified for the single extension use-case
|
||||
|
||||
"use strict";
|
||||
const es = require('event-stream');
|
||||
const filter = require('gulp-filter');
|
||||
const fs = require('fs');
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
const gulp = require('gulp');
|
||||
const glob = require('glob');
|
||||
const nlsDev = require('vscode-nls-dev');
|
||||
const path = require('path');
|
||||
const rimraf = require('rimraf');
|
||||
const shell = require('shelljs');
|
||||
const tsb = require('gulp-tsb');
|
||||
|
||||
const srcBase = path.join(__dirname, 'src');
|
||||
const src = path.join(srcBase, '**');
|
||||
const typeDefinitions = path.join(__dirname, 'node_modules/**/*.d.ts');
|
||||
const out = path.join('./', 'out');
|
||||
const i18n = path.join('./', 'i18n');
|
||||
const allErrors = [];
|
||||
let startTimer = null;
|
||||
let count = 0;
|
||||
const ts = require('gulp-typescript');
|
||||
const typescript = require('typescript');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
const del = require('del');
|
||||
const runSequence = require('run-sequence');
|
||||
const es = require('event-stream');
|
||||
const vsce = require('vsce');
|
||||
const nls = require('vscode-nls-dev');
|
||||
|
||||
// TASK: Add your supported languages here
|
||||
const languages = ['jpn'];
|
||||
const tsProject = ts.createProject('./tsconfig.json', { typescript });
|
||||
|
||||
function stripSourceMappingURL() {
|
||||
const input = es.through();
|
||||
const inlineMap = true;
|
||||
const inlineSource = false;
|
||||
const outDest = 'out';
|
||||
|
||||
const output = input.pipe(
|
||||
es.mapSync(f => {
|
||||
const contents = f.contents.toString('utf8');
|
||||
f.contents = new Buffer(
|
||||
contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''),
|
||||
'utf8'
|
||||
);
|
||||
return f;
|
||||
})
|
||||
);
|
||||
// If all VS Code langaues are support you can use nls.coreLanguages
|
||||
const languages = ['jpn'];
|
||||
|
||||
return es.duplex(input, output);
|
||||
}
|
||||
|
||||
function createPipeline(build) {
|
||||
const tsOptions = require(path.join(__dirname, 'tsconfig.json'))
|
||||
.compilerOptions;
|
||||
tsOptions.verbose = false;
|
||||
tsOptions.sourceMap = true;
|
||||
|
||||
tsOptions.inlineSources = !!build;
|
||||
const compilation = tsb.create(tsOptions);
|
||||
|
||||
return function() {
|
||||
const input = es.through();
|
||||
const tsFilter = filter(['**/*.ts', '!**/vscode-nls-dev/lib/**'], {
|
||||
restore: true
|
||||
});
|
||||
|
||||
const output = input
|
||||
.pipe(tsFilter)
|
||||
.pipe(compilation())
|
||||
.pipe(build ? nlsDev.rewriteLocalizeCalls() : es.through())
|
||||
.pipe(build ? stripSourceMappingURL() : es.through())
|
||||
.pipe(
|
||||
build
|
||||
? nlsDev.createAdditionalLanguageFiles(languages, i18n, out)
|
||||
: es.through()
|
||||
);
|
||||
|
||||
return es.duplex(input, output);
|
||||
};
|
||||
}
|
||||
|
||||
gulp.task('clean-extension', cb => rimraf(out, cb));
|
||||
|
||||
const iso639_3_to_2 = {
|
||||
chs: 'zh-cn',
|
||||
cht: 'zh-tw',
|
||||
csy: 'cs-cz',
|
||||
deu: 'de',
|
||||
enu: 'en',
|
||||
esn: 'es',
|
||||
fra: 'fr',
|
||||
hun: 'hu',
|
||||
ita: 'it',
|
||||
jpn: 'ja',
|
||||
kor: 'ko',
|
||||
nld: 'nl',
|
||||
plk: 'pl',
|
||||
ptb: 'pt-br',
|
||||
ptg: 'pt',
|
||||
rus: 'ru',
|
||||
sve: 'sv-se',
|
||||
trk: 'tr'
|
||||
};
|
||||
|
||||
gulp.task('prepare-package-nls-json', () => {
|
||||
languages.map(language => {
|
||||
const packageJson = path.join(i18n, language, 'package.i18n.json');
|
||||
console.log(packageJson);
|
||||
if (fs.existsSync(packageJson)) {
|
||||
shell.cp(packageJson, `package.nls.${iso639_3_to_2[language]}.json`);
|
||||
}
|
||||
});
|
||||
gulp.task('default', function(callback) {
|
||||
runSequence('build', callback);
|
||||
});
|
||||
|
||||
gulp.task(
|
||||
'build-extension',
|
||||
['clean-extension', 'prepare-package-nls-json'],
|
||||
() => {
|
||||
const pipeline = createPipeline(true);
|
||||
const input = gulp.src([src, typeDefinitions]);
|
||||
return input.pipe(pipeline()).pipe(gulp.dest(out));
|
||||
}
|
||||
);
|
||||
gulp.task('compile', function(callback) {
|
||||
runSequence('clean', 'internal-compile', callback);
|
||||
});
|
||||
|
||||
gulp.task('build', function(callback) {
|
||||
runSequence('clean', 'internal-nls-compile', 'add-i18n', callback);
|
||||
});
|
||||
|
||||
gulp.task('publish', function(callback) {
|
||||
runSequence('build', 'vsce:publish', callback);
|
||||
});
|
||||
|
||||
gulp.task('package', function(callback) {
|
||||
runSequence('build', 'vsce:package', callback);
|
||||
});
|
||||
|
||||
gulp.task('clean', function() {
|
||||
return del(['out/**', 'package.nls.*.json', 'i18n-sample*.vsix']);
|
||||
})
|
||||
|
||||
//---- internal
|
||||
|
||||
function compile(buildNls) {
|
||||
var r = tsProject.src()
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(tsProject()).js
|
||||
.pipe(buildNls ? nls.rewriteLocalizeCalls() : es.through())
|
||||
.pipe(buildNls ? nls.createAdditionalLanguageFiles(languages, 'i18n', 'out') : es.through());
|
||||
|
||||
if (inlineMap && inlineSource) {
|
||||
r = r.pipe(sourcemaps.write());
|
||||
} else {
|
||||
r = r.pipe(sourcemaps.write("../out", {
|
||||
// no inlined source
|
||||
includeContent: inlineSource,
|
||||
// Return relative source map root directories per file.
|
||||
sourceRoot: "../src"
|
||||
}));
|
||||
}
|
||||
|
||||
return r.pipe(gulp.dest(outDest));
|
||||
}
|
||||
|
||||
gulp.task('internal-compile', function() {
|
||||
return compile(false);
|
||||
});
|
||||
|
||||
gulp.task('internal-nls-compile', function() {
|
||||
return compile(true);
|
||||
});
|
||||
|
||||
gulp.task('add-i18n', function() {
|
||||
return gulp.src(['package.nls.json'])
|
||||
.pipe(nls.createAdditionalLanguageFiles(languages, 'i18n'))
|
||||
.pipe(gulp.dest('.'));
|
||||
});
|
||||
|
||||
gulp.task('vsce:publish', function() {
|
||||
return vsce.publish();
|
||||
});
|
||||
|
||||
gulp.task('vsce:package', function() {
|
||||
return vsce.createVSIX();
|
||||
});
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"sayBye.text": "さようなら"
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"sayHello.text": "こんにちは"
|
||||
}
|
||||
@ -1,51 +1,51 @@
|
||||
{
|
||||
"name": "i18n-sample",
|
||||
"displayName": "i18n-sample",
|
||||
"description": "Sample that shows how to localize an extension",
|
||||
"version": "0.0.2",
|
||||
"publisher": "vazexqi",
|
||||
"engines": {
|
||||
"vscode": "^1.13.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onCommand:extension.sayHello",
|
||||
"onCommand:extension.sayBye"
|
||||
],
|
||||
"main": "./out/src/extension",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "extension.sayHello",
|
||||
"title": "%extension.sayHello.title%"
|
||||
},
|
||||
{
|
||||
"command": "extension.sayBye",
|
||||
"title": "%extension.sayBye.title%"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "gulp build-extension",
|
||||
"compile": "tsc -watch -p ./",
|
||||
"clean": "gulp clean-extension",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^6.0.40",
|
||||
"event-stream": "^3.3.4",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-filter": "^5.0.0",
|
||||
"gulp-tsb": "^2.0.3",
|
||||
"rimraf": "^2.6.1",
|
||||
"shelljs": "^0.7.8",
|
||||
"typescript": "^2.4.1",
|
||||
"vscode": "^1.1.2",
|
||||
"vscode-nls-dev": "^2.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-nls": "^2.0.2"
|
||||
}
|
||||
}
|
||||
"name": "i18n-sample",
|
||||
"displayName": "i18n-sample",
|
||||
"description": "Sample that shows how to localize an extension",
|
||||
"version": "0.1.0",
|
||||
"publisher": "vazexqi",
|
||||
"engines": {
|
||||
"vscode": "^1.13.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onCommand:extension.sayHello",
|
||||
"onCommand:extension.sayBye"
|
||||
],
|
||||
"main": "./out/extension",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "extension.sayHello",
|
||||
"title": "%extension.sayHello.title%"
|
||||
},
|
||||
{
|
||||
"command": "extension.sayBye",
|
||||
"title": "%extension.sayBye.title%"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"watch": "tsc -watch -p ./",
|
||||
"clean": "gulp clean",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^6.0.40",
|
||||
"del": "^3.0.0",
|
||||
"event-stream": "^3.3.4",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-filter": "^5.0.1",
|
||||
"run-sequence": "^2.2.0",
|
||||
"typescript": "2.5.3",
|
||||
"gulp-typescript": "3.2.2",
|
||||
"vsce": "^1.32.0",
|
||||
"vscode": "^1.1.2",
|
||||
"vscode-nls-dev": "^2.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-nls": "^2.0.2"
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
{
|
||||
"extension.sayHello.title": "Hello",
|
||||
"extension.sayBye.title": "Bye"
|
||||
}
|
||||
"extension.sayHello.title": "Hello",
|
||||
"extension.sayBye.title": "Bye"
|
||||
}
|
||||
@ -1,9 +1,14 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export function sayByeCommand() {
|
||||
const message = localize('sayBye.text', 'Bye')
|
||||
vscode.window.showInformationMessage(message);
|
||||
}
|
||||
const message = localize('sayBye.text', 'Bye')
|
||||
vscode.window.showInformationMessage(message);
|
||||
}
|
||||
@ -1,3 +1,8 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.config(process.env.VSCODE_NLS_CONFIG)();
|
||||
|
||||
@ -5,17 +10,18 @@ import * as vscode from 'vscode';
|
||||
import { sayByeCommand } from './command/sayBye';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
const helloCmd = vscode.commands.registerCommand('extension.sayHello', () => {
|
||||
const message = localize('sayHello.text', 'Hello')
|
||||
vscode.window.showInformationMessage(message);
|
||||
});
|
||||
const helloCmd = vscode.commands.registerCommand('extension.sayHello', () => {
|
||||
const message = localize('sayHello.text', 'Hello')
|
||||
vscode.window.showInformationMessage(message);
|
||||
});
|
||||
|
||||
const byeCmd = vscode.commands.registerCommand(
|
||||
'extension.sayBye',
|
||||
sayByeCommand
|
||||
);
|
||||
const byeCmd = vscode.commands.registerCommand(
|
||||
'extension.sayBye',
|
||||
sayByeCommand
|
||||
);
|
||||
|
||||
context.subscriptions.push(helloCmd, byeCmd);
|
||||
context.subscriptions.push(helloCmd, byeCmd);
|
||||
}
|
||||
|
||||
export function deactivate() {}
|
||||
export function deactivate() {
|
||||
}
|
||||
@ -1,16 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"outDir": "out",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"sourceMap": true,
|
||||
"rootDir": "."
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
".vscode-test"
|
||||
]
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"outDir": "out",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"sourceMap": true,
|
||||
"rootDir": "src"
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user