Skip to content
This repository was archived by the owner on Nov 6, 2019. It is now read-only.

Commit c7c9f53

Browse files
author
Long Ho
committed
[feat] make this more flexible
1 parent 521f83b commit c7c9f53

13 files changed

+487
-238
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ jspm_packages
3737
.node_repl_history
3838

3939
test/fixture/*.js
40+
test/fixture/*.d.ts
4041
dist/

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77

88
Extracts string messages for translation from modules that use React Intl (similar to [`babel-plugin-react-intl`](https://github.com/yahoo/babel-plugin-react-intl)).
99

10-
Take a look at [`compile.ts`](compile.ts) for example in integration.
10+
Take a look at [`compile.ts`](compile.ts) for example in integration.

compile.ts

Lines changed: 55 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,58 @@
1-
import * as ts from 'typescript'
2-
import { sync as globSync } from 'glob'
3-
import { resolve } from 'path'
4-
import { transform as intlTransformer, aggregate } from './src'
1+
import * as ts from "typescript";
2+
import { sync as globSync } from "glob";
3+
import { transform as intlTransformer, aggregate } from "./src";
54

6-
declare module 'fs-extra' {
7-
export function outputJsonSync(file: string, data: any, opts?: {}): void;
5+
declare module "fs-extra" {
6+
export function outputJsonSync(file: string, data: any, opts?: {}): void;
87
}
9-
const { name: pkgName } = require(resolve(__dirname, 'package.json'))
10-
11-
const CJS_CONFIG = {
12-
experimentalDecorators: true,
13-
jsx: ts.JsxEmit.React,
14-
module: ts.ModuleKind.CommonJS,
15-
moduleResolution: ts.ModuleResolutionKind.NodeJs,
16-
noEmitOnError: false,
17-
noUnusedLocals: true,
18-
noUnusedParameters: true,
19-
stripInternal: true,
20-
target: ts.ScriptTarget.ES2015
8+
const CJS_CONFIG: ts.CompilerOptions = {
9+
experimentalDecorators: true,
10+
jsx: ts.JsxEmit.React,
11+
module: ts.ModuleKind.CommonJS,
12+
moduleResolution: ts.ModuleResolutionKind.NodeJs,
13+
noEmitOnError: false,
14+
noUnusedLocals: true,
15+
noUnusedParameters: true,
16+
stripInternal: true,
17+
declaration: true,
18+
baseUrl: __dirname,
19+
target: ts.ScriptTarget.ES2015
20+
};
21+
22+
export default function compile(
23+
input: string,
24+
options: ts.CompilerOptions = CJS_CONFIG
25+
) {
26+
const files = globSync(input);
27+
const compilerHost = ts.createCompilerHost(options);
28+
const program = ts.createProgram(files, options, compilerHost);
29+
30+
const msgs = {};
31+
32+
let emitResult = program.emit(undefined, undefined, undefined, undefined, {
33+
before: [
34+
intlTransformer({
35+
macroModuleSpecifier: "../../",
36+
interpolateName: "[hash:base64:10]",
37+
onMsgExtracted: aggregate(msgs),
38+
baseUrl: __dirname
39+
})
40+
]
41+
});
42+
43+
let allDiagnostics = ts
44+
.getPreEmitDiagnostics(program)
45+
.concat(emitResult.diagnostics);
46+
47+
allDiagnostics.forEach(diagnostic => {
48+
let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(
49+
diagnostic.start
50+
);
51+
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
52+
console.log(
53+
`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`
54+
);
55+
});
56+
57+
return msgs;
2158
}
22-
23-
export default function compile (input: string, options: ts.CompilerOptions = CJS_CONFIG) {
24-
const files = globSync(input)
25-
const compilerHost = ts.createCompilerHost(options)
26-
const program = ts.createProgram(files, options, compilerHost)
27-
28-
const msgs = {}
29-
30-
let emitResult = program.emit(undefined, undefined, undefined, undefined, {
31-
before: [
32-
intlTransformer({
33-
idPrefix: pkgName,
34-
onMsgExtracted: aggregate(msgs)
35-
})
36-
]
37-
})
38-
39-
let allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics)
40-
41-
allDiagnostics.forEach(diagnostic => {
42-
let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start)
43-
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')
44-
console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`)
45-
})
46-
47-
return msgs
48-
}

package-lock.json

Lines changed: 63 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"name": "ts-transform-react-intl",
3-
"version": "0.0.0-development",
3+
"version": "0.1.0",
44
"description": "Extracts string messages for translation from modules that use React Intl.",
55
"main": "dist/index.js",
66
"typings": "dist/index.d.ts",
77
"scripts": {
8-
"test": "rm -rf test/fixture/*.js && mocha --require ts-node/register test/*.test.ts",
8+
"test": "rm -rf test/fixture/*.js && tsc && mocha --require ts-node/register test/*.test.ts",
99
"prettier": "prettier --print-width=120 --tab-width=4 --single-quote --trailing-comma=es5 --no-semi --parser=typescript --write 'src/**/*.ts*' || true",
1010
"prepublishOnly": "tsc",
1111
"travis-deploy-once": "travis-deploy-once",
@@ -46,12 +46,16 @@
4646
"react": "^16.2.0",
4747
"react-intl": "^2.7.1",
4848
"ts-node": "^7.0.0",
49-
"typescript": "3",
5049
"travis-deploy-once": "^5.0.9",
5150
"semantic-release": "^15.9.17"
5251
},
5352
"pre-commit": [
5453
"prettier",
5554
"test"
56-
]
55+
],
56+
"dependencies": {
57+
"typescript": "3",
58+
"@types/loader-utils": "^1.1.3",
59+
"loader-utils": "^1.1.0"
60+
}
5761
}

src/aggregate.ts

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Messages } from 'react-intl'
2-
import { Extractor } from './transform'
1+
import { Messages } from "./types";
2+
import { Extractor } from "./transform";
33

44
/**
55
* Aggregate messages, inline modify msgs
@@ -8,48 +8,51 @@ import { Extractor } from './transform'
88
* @param {Messages} msgs messages map to aggregate to
99
* @returns {Extractor} extractor fn
1010
*/
11-
export default function aggregate(msgs: Messages): Extractor {
12-
const defaultMessages = Object.keys(msgs).reduce(
13-
(all, k) => {
14-
all[msgs[k].defaultMessage] = msgs[k]
15-
return all
16-
},
17-
{} as Messages
18-
)
11+
export function aggregate(msgs: Messages): Extractor {
12+
const defaultMessages = Object.keys(msgs).reduce(
13+
(all, k) => {
14+
all[msgs[k].defaultMessage] = msgs[k];
15+
return all;
16+
},
17+
{} as Messages
18+
);
1919

20-
return (trans: Messages) =>
21-
Object.keys(trans).forEach(k => {
22-
const msg = trans[k]
23-
const { id, description, defaultMessage } = trans[k]
24-
// Throw an error if we have messages with the same ID but different
25-
// description & defaultMessage
26-
if (
27-
msgs[id] &&
28-
(msgs[id].description !== msg.description || msgs[id].defaultMessage !== msg.defaultMessage)
29-
) {
30-
console.error(`
20+
return (trans: Messages) =>
21+
Object.keys(trans).forEach(k => {
22+
const msg = trans[k];
23+
const { id, description, defaultMessage } = trans[k];
24+
// Throw an error if we have messages with the same ID but different
25+
// description & defaultMessage
26+
if (
27+
msgs[id] &&
28+
(msgs[id].description !== msg.description ||
29+
msgs[id].defaultMessage !== msg.defaultMessage)
30+
) {
31+
console.error(`
3132
--- [ERR] Translation key ${k} already exists ---
3233
Description: "${msgs[id].description}" vs "${description}"
3334
Default Message: "${msgs[id].defaultMessage}" vs "${defaultMessage}"
34-
`)
35-
return process.exit(1)
36-
}
35+
`);
36+
return process.exit(1);
37+
}
3738

38-
// Warn if we have 2 messages with the same defaultMessage,
39-
// but different ID/description
40-
// For ex: Close can be Close Price or Close button
41-
if (
42-
defaultMessages[defaultMessage] &&
43-
(defaultMessages[defaultMessage].description !== msg.description ||
44-
defaultMessages[defaultMessage].id !== msg.id)
45-
) {
46-
console.warn(`
39+
// Warn if we have 2 messages with the same defaultMessage,
40+
// but different ID/description
41+
// For ex: Close can be Close Price or Close button
42+
if (
43+
defaultMessages[defaultMessage] &&
44+
(defaultMessages[defaultMessage].description !== msg.description ||
45+
defaultMessages[defaultMessage].id !== msg.id)
46+
) {
47+
console.warn(`
4748
--- [WARN]: Default Message ${defaultMessage} already exists ---
48-
Description: "${defaultMessages[defaultMessage].description}" vs "${description}"
49+
Description: "${
50+
defaultMessages[defaultMessage].description
51+
}" vs "${description}"
4952
ID: "${defaultMessages[defaultMessage].id}" vs "${id}"
50-
`)
51-
}
52-
msgs[id] = msg
53-
defaultMessages[defaultMessage] = msg
54-
})
53+
`);
54+
}
55+
msgs[id] = msg;
56+
defaultMessages[defaultMessage] = msg;
57+
});
5558
}

src/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
export { default as aggregate } from './aggregate'
2-
export { default as transform, Extractor } from './transform'
1+
export * from "./aggregate";
2+
export * from "./transform";
3+
export * from "./macro";

src/macro.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function _<T>(messages: T): T {
2+
return messages;
3+
}

0 commit comments

Comments
 (0)