From 7498a9579949d36ea78bd7a654a7848b80ecaeeb Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Wed, 27 Jun 2018 15:32:58 -0600 Subject: [PATCH] feat: drop support for transpiling the code that is being prevaled It cause way too many weird bugs that take a TON of time to track down. BREAKING CHANGE: Code that's being prevaled will no longer be transpiled. You should either transpile it ahead of time or only write the code in a version of JavaScript that runs natively in the version of node you're running. --- README.md | 86 +++-------------------- src/__tests__/.babelrc | 3 - src/__tests__/__snapshots__/index.js.snap | 51 +++----------- src/__tests__/fixtures/es6-identity.js | 12 +++- src/__tests__/fixtures/es6.js | 1 - src/__tests__/fixtures/transpiled.js | 4 -- src/__tests__/index.js | 14 +--- src/helpers.js | 19 ++--- src/index.js | 5 +- 9 files changed, 40 insertions(+), 155 deletions(-) delete mode 100644 src/__tests__/.babelrc delete mode 100644 src/__tests__/fixtures/es6.js delete mode 100644 src/__tests__/fixtures/transpiled.js diff --git a/README.md b/README.md index 2272a18..c4a4b12 100644 --- a/README.md +++ b/README.md @@ -94,8 +94,6 @@ See more below. - [Use with `babel-plugin-macros`](#use-with-babel-plugin-macros) - [Examples](#examples) - [Notes](#notes) -- [Limitations](#limitations) - - [Code transpilation](#code-transpilation) - [FAQ](#faq) - [How is this different from prepack?](#how-is-this-different-from-prepack) - [How is this different from webpack loaders?](#how-is-this-different-from-webpack-loaders) @@ -122,9 +120,8 @@ Important notes: 1. All code run by `preval` is _not_ run in a sandboxed environment 2. All code _must_ run synchronously. -3. The code string that preval evaluates will be transpiled, however, only that - code string will be prevaled. Learn more about this in the - [limitations](#limitations) section below. +3. Code that is run by preval is not transpiled so it must run natively in the + version of node you're running. (cannot use es modules). > You may like to watch > [this YouTube video](https://www.youtube.com/watch?v=1queadQ0048&list=PLV5CVI1eNcJgCrPH_e6d57KRUTiDZgs0u) @@ -339,77 +336,13 @@ Ok: } ``` -## Limitations - -### Code transpilation - -It's recommended that code you want to preval be written in a way that works in -the version of Node that you're running. That said, some code will be -transpiled. If you for some strange reason _really_ want to write your preval -code in a way that requires it to be transpiled, then expand here: - -
-Expand (beware) - -Here are a few examples of what will and wont be transpiled by preval: - -> This is assuming that you've configured babel to support ESModule syntax but -> you're using a node version which does not support ESModules natively. - -```javascript -// a.js // this file can use ESModules. Regular babel handles that. -import value from /* preval */ './b' - -// b.js // this file can use ESModules. preval handles that. -import c from './c' -export default c - -// c.js // this file cannot have ESModules in it. -// Neither preval nor babel will transpile this file's contents -module.exports = 'c' -``` - -```javascript -// this file can use ESModules -var x = preval` - // this string can use ESModules - import b from 'b.js' - // however b.js and it's dependents cannot -` -``` - -```javascript -// this file can use ESModules -// and b.js will be transpiled and evaluated -// by preval so it can use ESModules too -// but if b.js has dependencies then it cannot. -var x = preval.require('./b.js') -``` - -It's also notable that you can use preval in preval: - -```javascript -// this file can use ESModules -var x = preval` - // this string can use ESModules - import b from /* preval */ 'b.js' - // b can use ESModules (but not it's dependencies). -` -``` - -Again, this is admittedly pretty confusing, so it's strongly recommended that -any files you preval are written in a way that they work in node without needing -transpilation. - -
- ## FAQ ### How is this different from prepack? -[`prepack`][prepack] is intended to be run on your final bundle after you've run your -webpack/etc magic on it. It does a TON of stuff, but the idea is that your code -should work with or without prepack. +[`prepack`][prepack] is intended to be run on your final bundle after you've run +your webpack/etc magic on it. It does a TON of stuff, but the idea is that your +code should work with or without prepack. `babel-plugin-preval` is intended to let you write code that would _not_ work otherwise. Doing things like reading something from the file system are not @@ -420,14 +353,15 @@ possible in the browser (or with prepack), but `preval` enables you to do this. This plugin was inspired by webpack's [val-loader][val-loader]. The benefit of using this over that loader (or any other loader) is that it integrates with your existing babel pipeline. This is especially useful for the server where -you're probably not bundling your code with [`webpack`][webpack], but you may be using -babel. (If you're not using either, configuring babel for this would be easier -than configuring webpack for `val-loader`). +you're probably not bundling your code with [`webpack`][webpack], but you may be +using babel. (If you're not using either, configuring babel for this would be +easier than configuring webpack for `val-loader`). In addition, you can implement pretty much any webpack loader using `babel-plugin-preval`. -If you want to learn more, check `webpack` documentations about [`loaders`][webpack-loaders]. +If you want to learn more, check `webpack` documentations about +[`loaders`][webpack-loaders]. ## Inspiration diff --git a/src/__tests__/.babelrc b/src/__tests__/.babelrc deleted file mode 100644 index 73b5b0e..0000000 --- a/src/__tests__/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": [["env", {"targets": {"node": "8"}}]] -} diff --git a/src/__tests__/__snapshots__/index.js.snap b/src/__tests__/__snapshots__/index.js.snap index 8a296cf..f7a01bb 100644 --- a/src/__tests__/__snapshots__/index.js.snap +++ b/src/__tests__/__snapshots__/index.js.snap @@ -17,7 +17,7 @@ const x = preval\` const x = { "val": "# fixture\\n\\nThis is some file thing...\\n", - "getSplit": function getSplit(splitDelimiter) { + "getSplit": function (splitDelimiter) { return x.val.split(splitDelimiter); } }; @@ -34,19 +34,6 @@ const x = "/src/__tests__/index.js"; `; -exports[`preval can use preval in preval: can use preval in preval 1`] = ` - -var x = preval\` - import message from /* preval */ './fixtures/es6' - export default message -\` - - ↓ ↓ ↓ ↓ ↓ ↓ - -var x = "this string used exported default"; - -`; - exports[`preval dynamic error: dynamic error 1`] = ` const x = preval\`module.exports = "\${dynamic}"\` @@ -70,6 +57,16 @@ module.exports = undefined; `; +exports[`preval handles transpiled modules (uses default export): handles transpiled modules (uses default export) 1`] = ` + +let one = preval.require('./fixtures/es6-identity.js', 1) + + ↓ ↓ ↓ ↓ ↓ ↓ + +let one = 1; + +`; + exports[`preval import comment (with extras before): import comment (with extras before) 1`] = ` import x from /* this is extra stuff */ /* preval */ "./fixtures/compute-one.js" @@ -242,32 +239,6 @@ preval\`module.exports = "foo"\` `; -exports[`preval transpiled: transpiled 1`] = ` - -export default preval\` - import path from 'path' - export default path.join(__dirname, 'something/whatever.js').replace(__dirname, '') -\` - - ↓ ↓ ↓ ↓ ↓ ↓ - -export default "/something/whatever.js"; - -`; - -exports[`preval transpiles string contents: transpiles string contents 1`] = ` - -var x = preval\` - import one from './fixtures/compute-one' - export default one -\` - - ↓ ↓ ↓ ↓ ↓ ↓ - -var x = 1; - -`; - exports[`preval with flow after: with flow after 1`] = ` // @preval diff --git a/src/__tests__/fixtures/es6-identity.js b/src/__tests__/fixtures/es6-identity.js index e6de4ae..74f8a8b 100644 --- a/src/__tests__/fixtures/es6-identity.js +++ b/src/__tests__/fixtures/es6-identity.js @@ -1,5 +1,11 @@ -export default acceptsArg +/* eslint-disable */ +// codegen can't accept non-transpiled esmodules +// but it can handle transpiled esmodules +// so we're simulating a pre-transpiled module here +Object.defineProperty(exports, '__esModule', { + value: true, +}) -function acceptsArg(arg) { - return arg +exports.default = function(input) { + return input } diff --git a/src/__tests__/fixtures/es6.js b/src/__tests__/fixtures/es6.js deleted file mode 100644 index 8e31ae2..0000000 --- a/src/__tests__/fixtures/es6.js +++ /dev/null @@ -1 +0,0 @@ -export default `this string used exported default` diff --git a/src/__tests__/fixtures/transpiled.js b/src/__tests__/fixtures/transpiled.js deleted file mode 100644 index 208e19f..0000000 --- a/src/__tests__/fixtures/transpiled.js +++ /dev/null @@ -1,4 +0,0 @@ -export default preval` - import path from 'path' - export default path.join(__dirname, 'something/whatever.js').replace(__dirname, '') -` diff --git a/src/__tests__/index.js b/src/__tests__/index.js index b6379da..fae7e63 100644 --- a/src/__tests__/index.js +++ b/src/__tests__/index.js @@ -39,7 +39,6 @@ pluginTester({ \` `, 'a-bunch-of-checks': fixture('a-bunch-of-checks'), - transpiled: fixture('transpiled'), 'dynamic error': error( `const x = preval\`module.exports = "\${dynamic}"\``, ), @@ -93,17 +92,8 @@ pluginTester({ // @preval /* comment */ `), - 'transpiles string contents': ` - var x = preval\` - import one from './fixtures/compute-one' - export default one - \` - `, - 'can use preval in preval': ` - var x = preval\` - import message from /* preval */ './fixtures/es6' - export default message - \` + 'handles transpiled modules (uses default export)': ` + let one = preval.require('./fixtures/es6-identity.js', 1) `, }, }) diff --git a/src/helpers.js b/src/helpers.js index 584385d..436c9f3 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -1,25 +1,18 @@ const p = require('path') -const requireFromString = require('require-from-string') +const requireFromStringOfCode = require('require-from-string') const objectToAST = require('./object-to-ast') module.exports = { getReplacement, - transformAndRequire, + requireFromString, } -function transformAndRequire({ +function requireFromString({ string: stringToPreval, - fileOpts, + fileOpts: {filename}, args = [], - babel, }) { - const {filename, plugins, presets} = fileOpts - const {code} = babel.transform(stringToPreval, { - filename, - plugins, - presets, - }) - let mod = requireFromString(code, filename) + let mod = requireFromStringOfCode(String(stringToPreval), filename) mod = mod && mod.__esModule ? mod.default : mod if (typeof mod === 'function') { @@ -39,6 +32,6 @@ function transformAndRequire({ } function getReplacement({string, fileOpts, args, babel}) { - const mod = transformAndRequire({string, fileOpts, args, babel}) + const mod = requireFromString({string, fileOpts, args, babel}) return objectToAST(mod, {babel, fileOptions: fileOpts}) } diff --git a/src/index.js b/src/index.js index a60f543..ae624c4 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ const p = require('path') const fs = require('fs') // const printAST = require('ast-pretty-print') -const {getReplacement, transformAndRequire} = require('./helpers') +const {getReplacement, requireFromString} = require('./helpers') module.exports = prevalPlugin @@ -88,10 +88,9 @@ function prevalPlugin(babel) { let argValues if (prevalComment !== 'preval') { const arg = prevalComment.replace(/preval\((.*)\)/, '$1').trim() - const argValue = transformAndRequire({ + const argValue = requireFromString({ string: `module.exports = ${arg}`, fileOpts, - babel, }) argValues = [argValue] }