Skip to content

Commit

Permalink
added metadata passing from babel to webpack
Browse files Browse the repository at this point in the history
  • Loading branch information
Ognian committed Mar 5, 2017
1 parent 931c619 commit edebae7
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 0 deletions.
4 changes: 4 additions & 0 deletions package.json
Expand Up @@ -32,6 +32,10 @@
"eslint-plugin-flowtype": "^2.25.0",
"nyc": "^10.0.0",
"rimraf": "^2.4.3",
"react": "^15.1.0",
"react-intl":"^2.1.2",
"babel-plugin-react-intl": "^2.1.3",
"react-intl-webpack-plugin":"^0.0.3",
"webpack": "^2.2.0-rc"
},
"scripts": {
Expand Down
18 changes: 18 additions & 0 deletions src/index.js
Expand Up @@ -67,6 +67,7 @@ const transpile = function(source, options) {
}
const code = result.code;
const map = result.map;
const metadata = result.metadata;

if (map && (!map.sourcesContent || !map.sourcesContent.length)) {
map.sourcesContent = [source];
Expand All @@ -77,9 +78,16 @@ const transpile = function(source, options) {
return {
code: code,
map: map,
metadata: metadata,
};
};

function passMetadata(s, context, metadata) {
if (context[s]) {
context[s](metadata);
}
}

module.exports = function(source, inputSourceMap) {
// Handle filenames (#106)
const webpackRemainingChain = loaderUtils.getRemainingRequest(this).split("!");
Expand All @@ -90,6 +98,7 @@ module.exports = function(source, inputSourceMap) {
const loaderOptions = loaderUtils.parseQuery(this.query);
const userOptions = assign({}, globalOptions, loaderOptions);
const defaultOptions = {
metadataSubscribers: [],
inputSourceMap: inputSourceMap,
sourceRoot: process.cwd(),
filename: filename,
Expand Down Expand Up @@ -118,11 +127,14 @@ module.exports = function(source, inputSourceMap) {

const cacheDirectory = options.cacheDirectory;
const cacheIdentifier = options.cacheIdentifier;
const metadataSubscribers = options.metadataSubscribers;

delete options.cacheDirectory;
delete options.cacheIdentifier;
delete options.metadataSubscribers;

this.cacheable();
const context = this;

if (cacheDirectory) {
const callback = this.async();
Expand All @@ -134,10 +146,16 @@ module.exports = function(source, inputSourceMap) {
transform: transpile,
}, function(err, result) {
if (err) { return callback(err); }
metadataSubscribers.forEach(function (s) {
passMetadata(s, context, result.metadata);
});
return callback(null, result.code, result.map);
});
}

const result = transpile(source, options);
metadataSubscribers.forEach(function (s) {
passMetadata(s, context, result.metadata);
});
this.callback(null, result.code, result.map);
};
15 changes: 15 additions & 0 deletions test/fixtures/metadata.js
@@ -0,0 +1,15 @@
import {defineMessages} from 'react-intl';
class App {
constructor(arg='test') {
var m = defineMessages({
greeting: {
id: 'greetingId',
defaultMessage: 'Hello World!'
},
});

this.result = arg;
}
}

export default App;
16 changes: 16 additions & 0 deletions test/fixtures/metadataErr.js
@@ -0,0 +1,16 @@
import {defineMessages} from 'react-intl';
class App {
constructor(arg='test') {
var m = defineMessages({
greeting: {
id: 'greetingId',
defaultMessage: 'Hello World!'
},
});

bla bla
this.result = arg;
}
}

export default App;
154 changes: 154 additions & 0 deletions test/metadata.test.js
@@ -0,0 +1,154 @@
import test from "ava";
import fs from "fs";
import path from "path";
import assign from "object-assign";
import rimraf from "rimraf";
import webpack from "webpack";
import createTestDirectory from "./helpers/createTestDirectory";

const ReactIntlPlugin = require("react-intl-webpack-plugin");

const cacheDir = path.join(__dirname, "output/cache/cachefiles");
const outputDir = path.join(__dirname, "output/metadata");
const babelLoader = path.join(__dirname, "../lib");
const globalConfig = {
entry: "./test/fixtures/metadata.js",
output: {
path: outputDir,
filename: "[id].metadata.js",
},
plugins: [new ReactIntlPlugin(), ],
module: {
loaders: [
{
test: /\.jsx?/,
loader: babelLoader,
query: {
metadataSubscribers: [ReactIntlPlugin.metadataContextFunctionName],
plugins: [
["react-intl", { enforceDescriptions: false, }, ],
],
presets: [],
},
exclude: /node_modules/,
},
],
},
};

// Create a separate directory for each test so that the tests
// can run in parallel
test.cb.beforeEach((t) => {
createTestDirectory(outputDir, t.title, (err, directory) => {
if (err) return t.end(err);
t.context.directory = directory;
t.end();
});
});

test.cb.afterEach((t) => rimraf(t.context.directory, t.end));


test.cb("should pass metadata code snippet", (t) => {
const config = assign({}, globalConfig, {
output: {
path: t.context.directory,
filename: "[id].metadata.js",
},
});

webpack(config, (err) => {
t.is(err, null);

fs.readdir(t.context.directory, (err, files) => {
t.is(err, null);
t.true(files.length > 0);
fs.readFile(path.resolve(t.context.directory, "reactIntlMessages.json"),
function(err, data) {
t.is(err, null);
const text = data.toString();
const jsonText = JSON.parse(text);
t.true(jsonText.length == 1);
t.true(jsonText[0].id == "greetingId");
t.true(jsonText[0].defaultMessage == "Hello World!");
t.end();
});
});
});
});

test.cb("should not throw error", (t) => {
const config = assign({}, globalConfig, {
output: {
path: t.context.directory,
filename: "[id].metadata.js",
},
});

webpack(config, (err, stats) => {
t.is(err, null);
t.is(stats.compilation.errors.length, 0);
t.end();
});
});

test.cb("should throw error", (t) => {
const config = assign({}, globalConfig, {
output: {
path: t.context.directory,
filename: "[id].metadata.js",
},
entry: "./test/fixtures/metadataErr.js",
});

webpack(config, (err, stats) => {
t.is(err, null);
t.true(stats.compilation.errors.length > 0);
t.end();
});
});

test.cb("should pass metadata code snippet ( cache version )", (t) => {
const config = assign({}, globalConfig, {
output: {
path: t.context.directory,
filename: "[id].metadata.js",
},
module: {
loaders: [
{
test: /\.jsx?/,
loader: babelLoader,
query: {
metadataSubscribers: [ReactIntlPlugin.metadataContextFunctionName],
plugins: [
["react-intl", { enforceDescriptions: false, }, ],
],
cacheDirectory: cacheDir,
presets: [],
},
exclude: /node_modules/,
},
],
},
});

webpack(config, (err) => {
t.is(err, null);

fs.readdir(t.context.directory, (err, files) => {
t.is(err, null);
t.true(files.length > 0);
fs.readFile(path.resolve(t.context.directory, "reactIntlMessages.json"),
function(err, data) {
t.is(err, null);
const text = data.toString();
const jsonText = JSON.parse(text);
t.true(jsonText.length == 1);
t.true(jsonText[0].id == "greetingId");
t.true(jsonText[0].defaultMessage == "Hello World!");
t.end();
});
});
});
});

0 comments on commit edebae7

Please sign in to comment.