diff --git a/README.md b/README.md index 958f4f5..ecda60f 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,10 @@ You can read more about the background of this package [in this medium article]( Also make sure to check out and follow the guidelines of [react-intl](https://github.com/yahoo/react-intl) and [babel-plugin-react-intl](https://github.com/yahoo/babel-plugin-react-intl). +## Babel +- **1.x** works with Babel 7 +- **0.x** works with Babel 6 + ## Installation For global cli use only: ``` diff --git a/package.json b/package.json index 836a648..ec8c40c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@idagio/intl-utils", - "version": "0.0.4", + "version": "1.0.0", "description": "Utilities for managing l10n of react apps", "main": "src/index.js", "scripts": { @@ -25,8 +25,8 @@ "node": ">= 8.11.3" }, "dependencies": { - "babel-core": "^6.26.3", - "babel-plugin-react-intl": "^2.3.1", + "@babel/core": "^7.0.0", + "babel-plugin-react-intl": "^3.0.0", "chalk": "^2.4.1", "findit": "^2.0.0", "lodash": "^4.17.11" @@ -35,7 +35,12 @@ "intl-utils": "./bin/intl-utils.js" }, "devDependencies": { + "@babel/plugin-transform-runtime": "^7.2.0", + "@babel/preset-env": "^7.2.0", + "@babel/preset-react": "^7.0.0", "mocha": "^5.2.0", + "react": "^16.6.3", + "react-intl": "^2.7.2", "sinon": "^7.1.1" } } diff --git a/src/collect.js b/src/collect.js index 86c4e09..35c7bc6 100644 --- a/src/collect.js +++ b/src/collect.js @@ -1,13 +1,14 @@ -const babel = require('babel-core'); const fs = require('fs'); const path = require('path'); +const { pickBy, identity } = require('lodash'); +const babel = require('@babel/core'); module.exports = function collectMessages(fileTraverser, onCollected, babelConfigPath) { if (!babelConfigPath) { throw new Error('Please pass a path to your babel config'); } - const absolutePath = path.isAbsolute(babelConfigPath) ? - babelConfigPath + const absolutePath = path.isAbsolute(babelConfigPath) + ? babelConfigPath : path.join(process.cwd(), babelConfigPath); const babelConfig = JSON.parse(fs.readFileSync(absolutePath, 'utf8')); if (babelConfig.plugins) { @@ -20,13 +21,13 @@ module.exports = function collectMessages(fileTraverser, onCollected, babelConfi fileTraverser.on('file', (file) => { const fileExt = path.extname(file); if (fileExt === '.js' || fileExt === '.jsx') { - const code = fs.readFileSync(file, 'utf8'); - const transformed = babel.transform(code, babelConfig); + const transformed = babel.transformFileSync(file, babelConfig); const messages = transformed.metadata['react-intl'].messages; - aggregatedMessages = [...aggregatedMessages, ...messages]; + const messagesWithoutEmptyDescription = messages.map(message => pickBy(message, identity)); + + aggregatedMessages = [...aggregatedMessages, ...messagesWithoutEmptyDescription]; } }); fileTraverser.on('end', () => onCollected(aggregatedMessages)); - }; diff --git a/test/.fakebabelrc b/test/.fakebabelrc deleted file mode 100644 index 763ffa4..0000000 --- a/test/.fakebabelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["some-preset"], - "plugins": ["some-plugin"] -} diff --git a/test/collect.js b/test/collect.js index 2e37dba..c649af0 100644 --- a/test/collect.js +++ b/test/collect.js @@ -1,44 +1,11 @@ +const path = require('path'); const assert = require('assert'); const sinon = require('sinon'); + const EventEmitter = require('events'); const collect = require('../src/collect'); -// To be mocked -const fs = require('fs'); -const readFileSyncOriginal = fs.readFileSync; -const babel = require('babel-core'); -const path = require('path'); - -const messagesFile1 = [ - { - id: 'a', - defaultMessage: 'Message a', - }, - { - id: 'b', - defaultMessage: 'Message b', - } -]; - -const messagesFile2 = [ - { - id: 'c', - defaultMessage: 'Message c', - }, - { - id: 'd', - defaultMessage: 'Message d', - } -]; - -const messagesFile3 = [ - { - id: 'e', - defaultMessage: 'Message e', - } -]; - describe('Collect', function() { it('throws error if no babelConfigPath is supplied', function() { assert.throws( @@ -49,46 +16,23 @@ describe('Collect', function() { ); }); - it('loads babelconfig and aggregates messages passed from file traverser', function() { + it('loads babel config and aggregates messages passed from file traverser', function() { const onCollected = sinon.fake(); - const babelTransformSpy = sinon.spy((messages) => ({ - metadata: { - 'react-intl': { - messages, - } - } - })); const fileTraverser = new EventEmitter(); - sinon.replace(path, 'extname', () => '.js'); - sinon.replace(fs, 'readFileSync', (filePathOrMessages, encoding) => { - // We want it to work as normal for actual paths - if (typeof filePathOrMessages === 'string') { - return readFileSyncOriginal(filePathOrMessages, encoding) - } - // Fake to pass through the message objects emitted instead of paths - return filePathOrMessages; - }); - sinon.replace(babel, 'transform', babelTransformSpy); - - collect(fileTraverser, onCollected, './test/.fakebabelrc'); - fileTraverser.emit('file', messagesFile1); - fileTraverser.emit('file', messagesFile2); - fileTraverser.emit('file', messagesFile3); - fileTraverser.emit('end'); - assert.deepStrictEqual(babelTransformSpy.firstCall.args[1], { - presets: [ 'some-preset' ], - plugins: [ 'some-plugin', 'react-intl' ]} - ); + collect(fileTraverser, onCollected, './test/fixture/.babelrc'); + fileTraverser.emit('file', path.join(__dirname, 'fixture/component1.js')); + fileTraverser.emit('file', path.join(__dirname, 'fixture/component2.js')); + fileTraverser.emit('file', path.join(__dirname, 'fixture/component3.js')); - assert.ok(onCollected.calledWith([ - ...messagesFile1, - ...messagesFile2, - ...messagesFile3 - ])); - }); + fileTraverser.emit('end'); - afterEach(function() { - sinon.restore(); + assert.deepStrictEqual(onCollected.firstCall.args[0], [ + { id: 'a', defaultMessage: 'Message a' }, + { id: 'b', defaultMessage: 'Message b' }, + { id: 'c', defaultMessage: 'Message c' }, + { id: 'd', defaultMessage: 'Message d' }, + { id: 'e', defaultMessage: 'Message e', description: 'e' }, + ]); }); }); diff --git a/test/fixture/.babelrc b/test/fixture/.babelrc new file mode 100644 index 0000000..d301495 --- /dev/null +++ b/test/fixture/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@babel/preset-env", "@babel/preset-react"], + "plugins": ["@babel/plugin-transform-runtime"] +} diff --git a/test/fixture/component1.js b/test/fixture/component1.js new file mode 100644 index 0000000..169d312 --- /dev/null +++ b/test/fixture/component1.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { FormattedMessage } from 'react-intl'; + +module.exports = () => ( +