diff --git a/.all-contributorsrc b/.all-contributorsrc index 212b46a4a1d..27c22a86766 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -43,6 +43,15 @@ "contributions": [ "code" ] + }, + { + "login": "bengummer", + "name": "Ben Gummer", + "avatar_url": "https://avatars0.githubusercontent.com/u/1089897?v=3", + "profile": "https://github.com/bengummer", + "contributions": [ + "code" + ] } ] } diff --git a/README.md b/README.md index 8d3c204255c..337f86cda9c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# [CodeSandbox](https://codesandbox.io) [![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/KE3TbEZ) [![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors) [![Build Status](https://travis-ci.org/CompuIves/codesandbox-client.svg?branch=master)](https://travis-ci.org/CompuIves/codesandbox-client) +# [CodeSandbox](https://codesandbox.io) [![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/KE3TbEZ) [![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors) [![Build Status](https://travis-ci.org/CompuIves/codesandbox-client.svg?branch=master)](https://travis-ci.org/CompuIves/codesandbox-client) An online code editor with a focus on React. @@ -44,8 +44,8 @@ CodeSandbox consists several separate servers, some of these are open sourced. Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)): -| [
Ives van Hoorne](http://ivesvh.com)
[💬](#question-CompuIves "Answering Questions") [📝](#blog-CompuIves "Blogposts") [🐛](https://github.com/CompuIves/CodeSandbox/issues?q=author%3ACompuIves "Bug reports") [💻](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Code") [🎨](#design-CompuIves "Design") [📖](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Documentation") [💡](#example-CompuIves "Examples") [🚇](#infra-CompuIves "Infrastructure (Hosting, Build-Tools, etc)") [👀](#review-CompuIves "Reviewed Pull Requests") [⚠️](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Tests") [🔧](#tool-CompuIves "Tools") | [
Donavon West](http://donavon.com)
[💻](https://github.com/CompuIves/CodeSandbox/commits?author=donavon "Code") | [
Jeff Allen](http://www.jeffallen.io/)
[💻](https://github.com/CompuIves/CodeSandbox/commits?author=vueu "Code") | -| :---: | :---: | :---: | +| [
Ives van Hoorne](http://ivesvh.com)
[💬](#question-CompuIves "Answering Questions") [📝](#blog-CompuIves "Blogposts") [🐛](https://github.com/CompuIves/CodeSandbox/issues?q=author%3ACompuIves "Bug reports") [💻](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Code") [🎨](#design-CompuIves "Design") [📖](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Documentation") [💡](#example-CompuIves "Examples") [🚇](#infra-CompuIves "Infrastructure (Hosting, Build-Tools, etc)") [👀](#review-CompuIves "Reviewed Pull Requests") [⚠️](https://github.com/CompuIves/CodeSandbox/commits?author=CompuIves "Tests") [🔧](#tool-CompuIves "Tools") | [
Donavon West](http://donavon.com)
[💻](https://github.com/CompuIves/CodeSandbox/commits?author=donavon "Code") | [
Jeff Allen](http://www.jeffallen.io/)
[💻](https://github.com/CompuIves/CodeSandbox/commits?author=vueu "Code") | [
Ben Gummer](https://github.com/bengummer)
[💻](https://github.com/CompuIves/CodeSandbox/commits?author=bengummer "Code") | +| :---: | :---: | :---: | :---: | This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome! diff --git a/src/sandbox/eval/index.js b/src/sandbox/eval/index.js index 7ee4a8c3abc..e13f98347a3 100644 --- a/src/sandbox/eval/index.js +++ b/src/sandbox/eval/index.js @@ -19,7 +19,7 @@ function doEval( const html = /\.html$/; const css = /\.css$/; const json = /\.json$/; - const js = /\.js$/; + const js = /\.jsx?$/; if (html.test(mainModule.title)) { return evalRaw( diff --git a/src/sandbox/eval/index.test.js b/src/sandbox/eval/index.test.js index 571b8281679..34b7ecfd8b1 100644 --- a/src/sandbox/eval/index.test.js +++ b/src/sandbox/eval/index.test.js @@ -3,223 +3,225 @@ import { clearCache } from './js'; describe('eval', () => { // just evaluate if the right evallers are called - describe('js', () => { - beforeEach(() => { - clearCache(); - }); - - test('default es exports', () => { - const mainModule = { - title: 'test.js', - code: ` - export default 3; - `, - }; - - expect(evaller(mainModule, [], [])).toEqual({ default: 3 }); - }); - - test('multiple es exports', () => { - const mainModule = { - title: 'test.js', - code: ` - export const a = 'b'; - export const b = 'c'; - export default 3; - `, - }; - - expect(evaller(mainModule, [], [])).toEqual({ - a: 'b', - b: 'c', - default: 3, - }); - }); - - test('node exports', () => { - const mainModule = { - title: 'test.js', - code: ` - module.exports = 3; - `, - }; - - expect(evaller(mainModule, [], [])).toEqual(3); - }); - - test('imports', () => { - const mainModule = { - title: 'test.js', - shortid: '1', - code: ` - export default require('./test2'); - `, - }; - - const secondModule = { - title: 'test2.js', - shortid: '2', - code: ` - export default 3; - `, - }; - - expect(evaller(mainModule, [mainModule, secondModule], [])).toEqual({ - default: { default: 3 }, + ['js', 'jsx'].forEach(jsExtension => { + describe(jsExtension, () => { + beforeEach(() => { + clearCache(); }); - }); - - describe('cyclic dependencies', () => { - it('returns an object as cyclic dependency', () => { - const moduleA = { - title: 'a.js', - shortid: '1', - code: ` - import b from './b'; - export default b; - `, - }; - const moduleB = { - title: 'b.js', - shortid: '2', + test('default es exports', () => { + const mainModule = { + title: `test.${jsExtension}`, code: ` - import a from './a'; - export default a; - `, + export default 3; + `, }; - expect(evaller(moduleA, [moduleA, moduleB], [])).toEqual({ - default: {}, - }); + expect(evaller(mainModule, [], [])).toEqual({ default: 3 }); }); - it('returns an object in deep cyclic dependency', () => { - const moduleA = { - title: 'a.js', - shortid: '1', + test('multiple es exports', () => { + const mainModule = { + title: `test.${jsExtension}`, code: ` - import b from './b'; - export default b; - `, + export const a = 'b'; + export const b = 'c'; + export default 3; + `, }; - const moduleB = { - title: 'b.js', - shortid: '2', - code: ` - import c from './c'; - export default c; - `, - }; + expect(evaller(mainModule, [], [])).toEqual({ + a: 'b', + b: 'c', + default: 3, + }); + }); - const moduleC = { - title: 'c.js', - shortid: '3', + test('node exports', () => { + const mainModule = { + title: `test.${jsExtension}`, code: ` - import a from './a'; - export default a; - `, + module.exports = 3; + `, }; - expect(evaller(moduleA, [moduleA, moduleB, moduleC], [])).toEqual({ - default: {}, - }); + expect(evaller(mainModule, [], [])).toEqual(3); }); - }); - describe.skip('custom babel config', () => { - it('uses custom babel config', () => { + test('imports', () => { const mainModule = { - title: 'test.js', + title: `test.${jsExtension}`, shortid: '1', code: ` - const a = {b: 'a'}; - const b = {a: 'b'}; - export default {...a, ...b}; - `, + export default require('./test2'); + `, }; - const babelConfig = { - title: '.babelrc', + const secondModule = { + title: `test2.${jsExtension}`, shortid: '2', code: ` - { - "presets": ["es2015", "react", "stage-0"] - } - `, + export default 3; + `, }; - expect(evaller(mainModule, [mainModule, babelConfig], [])).toEqual({ - default: { a: 'b', b: 'a' }, + expect(evaller(mainModule, [mainModule, secondModule], [])).toEqual({ + default: { default: 3 }, }); - - const emptyBabelConfig = { - title: '.babelrc', - shortid: '2', - code: ` - { - "presets": [] - }`, - }; - - expect(() => - evaller(mainModule, [mainModule, emptyBabelConfig], []), - ).toThrow(); }); - it('resolves to dependencies as plugins', () => { - const mainModule = { - title: 'test.js', - shortid: '1', - code: ` - const a = {b: 'a'}; - const b = {a: 'b'}; - export default {...a, ...b}; - `, - }; - - const babelConfig = { - title: '.babelrc', - shortid: '2', - code: ` - { - "presets": ["es2015", "react", "stage-0"], - "plugins": ["emotion/babel"] - } - `, - }; + describe('cyclic dependencies', () => { + it('returns an object as cyclic dependency', () => { + const moduleA = { + title: `a.${jsExtension}`, + shortid: '1', + code: ` + import b from './b'; + export default b; + `, + }; + + const moduleB = { + title: `b.${jsExtension}`, + shortid: '2', + code: ` + import a from './a'; + export default a; + `, + }; + + expect(evaller(moduleA, [moduleA, moduleB], [])).toEqual({ + default: {}, + }); + }); - expect(() => - evaller(mainModule, [mainModule, babelConfig], [], {}), - ).toThrowError("Could not find dependency: 'emotion'"); + it('returns an object in deep cyclic dependency', () => { + const moduleA = { + title: `a.${jsExtension}`, + shortid: '1', + code: ` + import b from './b'; + export default b; + `, + }; + + const moduleB = { + title: `b.${jsExtension}`, + shortid: '2', + code: ` + import c from './c'; + export default c; + `, + }; + + const moduleC = { + title: `c.${jsExtension}`, + shortid: '3', + code: ` + import a from './a'; + export default a; + `, + }; + + expect(evaller(moduleA, [moduleA, moduleB, moduleC], [])).toEqual({ + default: {}, + }); + }); }); - it('can resolve plugins with options', () => { - const mainModule = { - title: 'test.js', - shortid: '1', - code: ` - const a = {b: 'a'}; - const b = {a: 'b'}; - export default {...a, ...b}; - `, - }; + describe.skip('custom babel config', () => { + it('uses custom babel config', () => { + const mainModule = { + title: `test.${jsExtension}`, + shortid: '1', + code: ` + const a = {b: 'a'}; + const b = {a: 'b'}; + export default {...a, ...b}; + `, + }; + + const babelConfig = { + title: '.babelrc', + shortid: '2', + code: ` + { + "presets": ["es2015", "react", "stage-0"] + } + `, + }; + + expect(evaller(mainModule, [mainModule, babelConfig], [])).toEqual({ + default: { a: 'b', b: 'a' }, + }); + + const emptyBabelConfig = { + title: '.babelrc', + shortid: '2', + code: ` + { + "presets": [] + }`, + }; + + expect(() => + evaller(mainModule, [mainModule, emptyBabelConfig], []), + ).toThrow(); + }); - const babelConfig = { - title: '.babelrc', - shortid: '2', - code: ` - { - "presets": ["es2015", "react", "stage-0"], - "plugins": [["emotion/babel", { "inline": true }]] - } - `, - }; + it('resolves to dependencies as plugins', () => { + const mainModule = { + title: `test.${jsExtension}`, + shortid: '1', + code: ` + const a = {b: 'a'}; + const b = {a: 'b'}; + export default {...a, ...b}; + `, + }; + + const babelConfig = { + title: '.babelrc', + shortid: '2', + code: ` + { + "presets": ["es2015", "react", "stage-0"], + "plugins": ["emotion/babel"] + } + `, + }; + + expect(() => + evaller(mainModule, [mainModule, babelConfig], [], {}), + ).toThrowError("Could not find dependency: 'emotion'"); + }); - expect(() => - evaller(mainModule, [mainModule, babelConfig], [], {}), - ).toThrowError("Could not find dependency: 'emotion'"); + it('can resolve plugins with options', () => { + const mainModule = { + title: `test.${jsExtension}`, + shortid: '1', + code: ` + const a = {b: 'a'}; + const b = {a: 'b'}; + export default {...a, ...b}; + `, + }; + + const babelConfig = { + title: '.babelrc', + shortid: '2', + code: ` + { + "presets": ["es2015", "react", "stage-0"], + "plugins": [["emotion/babel", { "inline": true }]] + } + `, + }; + + expect(() => + evaller(mainModule, [mainModule, babelConfig], [], {}), + ).toThrowError("Could not find dependency: 'emotion'"); + }); }); }); }); diff --git a/src/sandbox/utils/resolve-module.js b/src/sandbox/utils/resolve-module.js index 9288faed8dc..58069f1d7f2 100644 --- a/src/sandbox/utils/resolve-module.js +++ b/src/sandbox/utils/resolve-module.js @@ -3,7 +3,7 @@ import type { Module, Directory } from 'common/types'; const compareTitle = (original: string, test: string) => { if (original === test) return true; - if (original === `${test}.js`) return true; + if (original === `${test}.js` || original === `${test}.jsx`) return true; return false; };