Skip to content

Commit 1fbbdf3

Browse files
Ogniandanez
authored andcommitted
added metadata passing from babel to webpack (#398)
1 parent 2fbcc01 commit 1fbbdf3

File tree

5 files changed

+207
-0
lines changed

5 files changed

+207
-0
lines changed

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
"eslint-plugin-flowtype": "^2.25.0",
3333
"nyc": "^10.0.0",
3434
"rimraf": "^2.4.3",
35+
"react": "^15.1.0",
36+
"react-intl":"^2.1.2",
37+
"babel-plugin-react-intl": "^2.1.3",
38+
"react-intl-webpack-plugin":"^0.0.3",
3539
"webpack": "^2.2.0-rc"
3640
},
3741
"scripts": {

src/index.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ const transpile = function(source, options) {
6767
}
6868
const code = result.code;
6969
const map = result.map;
70+
const metadata = result.metadata;
7071

7172
if (map && (!map.sourcesContent || !map.sourcesContent.length)) {
7273
map.sourcesContent = [source];
@@ -77,9 +78,16 @@ const transpile = function(source, options) {
7778
return {
7879
code: code,
7980
map: map,
81+
metadata: metadata,
8082
};
8183
};
8284

85+
function passMetadata(s, context, metadata) {
86+
if (context[s]) {
87+
context[s](metadata);
88+
}
89+
}
90+
8391
module.exports = function(source, inputSourceMap) {
8492
// Handle filenames (#106)
8593
const webpackRemainingChain = loaderUtils.getRemainingRequest(this).split("!");
@@ -90,6 +98,7 @@ module.exports = function(source, inputSourceMap) {
9098
const loaderOptions = loaderUtils.parseQuery(this.query);
9199
const userOptions = assign({}, globalOptions, loaderOptions);
92100
const defaultOptions = {
101+
metadataSubscribers: [],
93102
inputSourceMap: inputSourceMap,
94103
sourceRoot: process.cwd(),
95104
filename: filename,
@@ -118,11 +127,14 @@ module.exports = function(source, inputSourceMap) {
118127

119128
const cacheDirectory = options.cacheDirectory;
120129
const cacheIdentifier = options.cacheIdentifier;
130+
const metadataSubscribers = options.metadataSubscribers;
121131

122132
delete options.cacheDirectory;
123133
delete options.cacheIdentifier;
134+
delete options.metadataSubscribers;
124135

125136
this.cacheable();
137+
const context = this;
126138

127139
if (cacheDirectory) {
128140
const callback = this.async();
@@ -134,10 +146,16 @@ module.exports = function(source, inputSourceMap) {
134146
transform: transpile,
135147
}, function(err, result) {
136148
if (err) { return callback(err); }
149+
metadataSubscribers.forEach(function (s) {
150+
passMetadata(s, context, result.metadata);
151+
});
137152
return callback(null, result.code, result.map);
138153
});
139154
}
140155

141156
const result = transpile(source, options);
157+
metadataSubscribers.forEach(function (s) {
158+
passMetadata(s, context, result.metadata);
159+
});
142160
this.callback(null, result.code, result.map);
143161
};

test/fixtures/metadata.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {defineMessages} from 'react-intl';
2+
class App {
3+
constructor(arg='test') {
4+
var m = defineMessages({
5+
greeting: {
6+
id: 'greetingId',
7+
defaultMessage: 'Hello World!'
8+
},
9+
});
10+
11+
this.result = arg;
12+
}
13+
}
14+
15+
export default App;

test/fixtures/metadataErr.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {defineMessages} from 'react-intl';
2+
class App {
3+
constructor(arg='test') {
4+
var m = defineMessages({
5+
greeting: {
6+
id: 'greetingId',
7+
defaultMessage: 'Hello World!'
8+
},
9+
});
10+
11+
bla bla
12+
this.result = arg;
13+
}
14+
}
15+
16+
export default App;

test/metadata.test.js

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import test from "ava";
2+
import fs from "fs";
3+
import path from "path";
4+
import assign from "object-assign";
5+
import rimraf from "rimraf";
6+
import webpack from "webpack";
7+
import createTestDirectory from "./helpers/createTestDirectory";
8+
9+
const ReactIntlPlugin = require("react-intl-webpack-plugin");
10+
11+
const cacheDir = path.join(__dirname, "output/cache/cachefiles");
12+
const outputDir = path.join(__dirname, "output/metadata");
13+
const babelLoader = path.join(__dirname, "../lib");
14+
const globalConfig = {
15+
entry: "./test/fixtures/metadata.js",
16+
output: {
17+
path: outputDir,
18+
filename: "[id].metadata.js",
19+
},
20+
plugins: [new ReactIntlPlugin(), ],
21+
module: {
22+
loaders: [
23+
{
24+
test: /\.jsx?/,
25+
loader: babelLoader,
26+
query: {
27+
metadataSubscribers: [ReactIntlPlugin.metadataContextFunctionName],
28+
plugins: [
29+
["react-intl", { enforceDescriptions: false, }, ],
30+
],
31+
presets: [],
32+
},
33+
exclude: /node_modules/,
34+
},
35+
],
36+
},
37+
};
38+
39+
// Create a separate directory for each test so that the tests
40+
// can run in parallel
41+
test.cb.beforeEach((t) => {
42+
createTestDirectory(outputDir, t.title, (err, directory) => {
43+
if (err) return t.end(err);
44+
t.context.directory = directory;
45+
t.end();
46+
});
47+
});
48+
49+
test.cb.afterEach((t) => rimraf(t.context.directory, t.end));
50+
51+
52+
test.cb("should pass metadata code snippet", (t) => {
53+
const config = assign({}, globalConfig, {
54+
output: {
55+
path: t.context.directory,
56+
filename: "[id].metadata.js",
57+
},
58+
});
59+
60+
webpack(config, (err) => {
61+
t.is(err, null);
62+
63+
fs.readdir(t.context.directory, (err, files) => {
64+
t.is(err, null);
65+
t.true(files.length > 0);
66+
fs.readFile(path.resolve(t.context.directory, "reactIntlMessages.json"),
67+
function(err, data) {
68+
t.is(err, null);
69+
const text = data.toString();
70+
const jsonText = JSON.parse(text);
71+
t.true(jsonText.length == 1);
72+
t.true(jsonText[0].id == "greetingId");
73+
t.true(jsonText[0].defaultMessage == "Hello World!");
74+
t.end();
75+
});
76+
});
77+
});
78+
});
79+
80+
test.cb("should not throw error", (t) => {
81+
const config = assign({}, globalConfig, {
82+
output: {
83+
path: t.context.directory,
84+
filename: "[id].metadata.js",
85+
},
86+
});
87+
88+
webpack(config, (err, stats) => {
89+
t.is(err, null);
90+
t.is(stats.compilation.errors.length, 0);
91+
t.end();
92+
});
93+
});
94+
95+
test.cb("should throw error", (t) => {
96+
const config = assign({}, globalConfig, {
97+
output: {
98+
path: t.context.directory,
99+
filename: "[id].metadata.js",
100+
},
101+
entry: "./test/fixtures/metadataErr.js",
102+
});
103+
104+
webpack(config, (err, stats) => {
105+
t.is(err, null);
106+
t.true(stats.compilation.errors.length > 0);
107+
t.end();
108+
});
109+
});
110+
111+
test.cb("should pass metadata code snippet ( cache version )", (t) => {
112+
const config = assign({}, globalConfig, {
113+
output: {
114+
path: t.context.directory,
115+
filename: "[id].metadata.js",
116+
},
117+
module: {
118+
loaders: [
119+
{
120+
test: /\.jsx?/,
121+
loader: babelLoader,
122+
query: {
123+
metadataSubscribers: [ReactIntlPlugin.metadataContextFunctionName],
124+
plugins: [
125+
["react-intl", { enforceDescriptions: false, }, ],
126+
],
127+
cacheDirectory: cacheDir,
128+
presets: [],
129+
},
130+
exclude: /node_modules/,
131+
},
132+
],
133+
},
134+
});
135+
136+
webpack(config, (err) => {
137+
t.is(err, null);
138+
139+
fs.readdir(t.context.directory, (err, files) => {
140+
t.is(err, null);
141+
t.true(files.length > 0);
142+
fs.readFile(path.resolve(t.context.directory, "reactIntlMessages.json"),
143+
function(err, data) {
144+
t.is(err, null);
145+
const text = data.toString();
146+
const jsonText = JSON.parse(text);
147+
t.true(jsonText.length == 1);
148+
t.true(jsonText[0].id == "greetingId");
149+
t.true(jsonText[0].defaultMessage == "Hello World!");
150+
t.end();
151+
});
152+
});
153+
});
154+
});

0 commit comments

Comments
 (0)