From 1871902532991fb9d22409d240de952b2e0b0f5e Mon Sep 17 00:00:00 2001 From: Ognian Tschakalov Date: Mon, 30 May 2016 19:24:06 +0200 Subject: [PATCH] feat(config): add metadataSubscribes option - add metadataSubscribers option as an array of context functions to call - pass metadata to metadataSubscribers functions --- package.json | 4 + src/index.js | 19 +++++ test/fixtures/metadata.js | 15 ++++ test/fixtures/metadataErr.js | 16 ++++ test/metadata.test.js | 137 +++++++++++++++++++++++++++++++++++ 5 files changed, 191 insertions(+) create mode 100644 test/fixtures/metadata.js create mode 100644 test/fixtures/metadataErr.js create mode 100644 test/metadata.test.js diff --git a/package.json b/package.json index ae486626..4ac9b629 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "babel-core": "^6.0.0", "babel-eslint": "^7.1.0", "babel-plugin-istanbul": "^2.0.3", + "babel-plugin-react-intl": "2.1.3", "babel-preset-es2015": "^6.0.0", "babel-preset-latest": "^6.16.0", "codecov": "^1.0.1", @@ -31,6 +32,9 @@ "eslint-plugin-babel": "^3.3.0", "eslint-plugin-flowtype": "^2.25.0", "nyc": "^8.3.2", + "react": "^15.1.0", + "react-intl":"^2.1.2", + "react-intl-webpack-plugin":"0.0.3", "rimraf": "^2.4.3", "webpack": "2.1.0-beta.22" }, diff --git a/src/index.js b/src/index.js index 3c5caf81..0a3483ad 100644 --- a/src/index.js +++ b/src/index.js @@ -56,6 +56,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]; @@ -64,9 +65,17 @@ 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) { let result = {}; @@ -79,6 +88,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, @@ -107,11 +117,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(); @@ -123,10 +136,16 @@ module.exports = function(source, inputSourceMap) { transform: transpile, }, function(err, result) { if (err) { return callback(err); } + metadataSubscribers.map(function(s) { + passMetadata(s, context, result.metadata); + }); return callback(null, result.code, result.map); }); } result = transpile(source, options); + metadataSubscribers.map(function(s) { + passMetadata(s, context, result.metadata); + }); this.callback(null, result.code, result.map); }; diff --git a/test/fixtures/metadata.js b/test/fixtures/metadata.js new file mode 100644 index 00000000..bc093acb --- /dev/null +++ b/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; diff --git a/test/fixtures/metadataErr.js b/test/fixtures/metadataErr.js new file mode 100644 index 00000000..1b05d3e0 --- /dev/null +++ b/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; diff --git a/test/metadata.test.js b/test/metadata.test.js new file mode 100644 index 00000000..93c9584a --- /dev/null +++ b/test/metadata.test.js @@ -0,0 +1,137 @@ +"use strict"; + +import fs from "fs"; +import path from "path"; +import assign from "object-assign"; +import test from "ava"; +import mkdirp from "mkdirp"; +import rimraf from "rimraf"; +import webpack from "webpack"; +import ReactIntlPlugin from "react-intl-webpack-plugin"; + +const cacheDir = path.resolve(__dirname, "./output/cache/cachefiles"); +const outputDir = path.resolve(__dirname, "./output/metadata"); +const babelLoader = path.resolve(__dirname, "../"); +const globalConfig = { + entry: path.join(__dirname, "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) => { + const directory = path.join(outputDir, t.title.replace(/ /g, "_")); + t.context.directory = directory; + rimraf(directory, (err) => { + if (err) return t.end(err); + mkdirp(directory, t.end); + }); +}); + +test.cb.afterEach((t) => rimraf(t.context.directory, t.end)); + +test.cb("should pass metadata code snippet", function(t) { + const config = assign({}, globalConfig, { + }); + + webpack(config, function(err) { + t.is(err, null); + + fs.readdir(outputDir, function(err) { + t.is(err, null); + fs.readFile(path.resolve(outputDir, "reactIntlMessages.json"), + function(err, data) { + const text = data.toString(); + t.is(err, null); + const jsonText = JSON.parse(text); + t.is(jsonText.length, 1); + t.is(jsonText[0].id, "greetingId"); + t.is(jsonText[0].defaultMessage, "Hello World!"); + + t.end(); + }); + }); + }); +}); + +test.cb("should not throw error ", function(t) { + const config = assign({}, globalConfig, {}); + + webpack(config, function(err, stats) { + t.is(stats.compilation.errors.length, 0); + t.end(); + }); +}); + +test.cb("should throw error ", function(t) { + const config = assign({}, globalConfig, { + entry: "./test/fixtures/metadataErr.js", + }); + + webpack(config, function(err, stats) { + t.true(stats.compilation.errors.length > 0); + t.end(); + }); +}); + +test.cb("should pass metadata code snippet (cache version)", function(t) { + const config = assign({}, globalConfig, { + module: { + loaders: [ + { + test: /\.jsx?/, + loader: babelLoader, + query: { + metadataSubscribers: + [ReactIntlPlugin.metadataContextFunctionName], + plugins: [ + ["react-intl", {enforceDescriptions: false,},], + ], + cacheDirectory: cacheDir, + presets: [], + }, + exclude: /node_modules/, + }, + ], + }, + }); + + webpack(config, function(err) { + t.is(err, null); + + fs.readdir(outputDir, function(err) { + t.is(err, null); + fs.readFile(path.resolve(outputDir, "reactIntlMessages.json"), + function(err, data) { + const text = data.toString(); + t.is(err, null); + const jsonText = JSON.parse(text); + t.is(jsonText.length, 1); + t.is(jsonText[0].id, "greetingId"); + t.is(jsonText[0].defaultMessage, "Hello World!"); + + t.end(); + }); + }); + }); +});