Giter VIP home page Giter VIP logo

babel-plugin-preval's Introduction

babel-plugin-preval

Pre-evaluate code at build-time


Build Status Code Coverage version downloads MIT License

All Contributors

PRs Welcome Code of Conduct Babel Macro Examples

The problem

You need to do some dynamic stuff, but don't want to do it at runtime. Or maybe you want to do stuff like read the filesystem to get a list of files and you can't do that in the browser.

This solution

This allows you to specify some code that runs in Node and whatever you module.exports in there will be swapped. For example:

const x = preval`module.exports = 1`

//      โ†“ โ†“ โ†“ โ†“ โ†“ โ†“

const x = 1

Or, more interestingly:

const x = preval`
  const fs = require('fs')
  const val = fs.readFileSync(__dirname + '/fixture1.md', 'utf8')
  module.exports = {
    val,
    getSplit: function(splitDelimiter) {
      return x.val.split(splitDelimiter)
    }
  }
`

//      โ†“ โ†“ โ†“ โ†“ โ†“ โ†“

const x = {
  val: '# fixture\n\nThis is some file thing...\n',
  getSplit: function getSplit(splitDelimiter) {
    return x.val.split(splitDelimiter)
  },
}

There's also preval.require('./something') and import x from /* preval */ './something' (which can both take some arguments) or add // @preval comment at the top of a file.

See more below.

Table of Contents

Installation

This module is distributed via npm which is bundled with node and should be installed as one of your project's devDependencies:

npm install --save-dev babel-plugin-preval

Usage

Important notes:

  1. All code run by preval is not run in a sandboxed environment
  2. All code must run synchronously.
  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 to get an idea of what preval is and how it can be used.

Template Tag

Before:

const greeting = preval`
  const fs = require('fs')
  module.exports = fs.readFileSync(require.resolve('./greeting.txt'), 'utf8')
`

After (assuming greeting.txt contains the text: "Hello world!"):

const greeting = 'Hello world!'

preval can also handle some simple dynamic values as well:

Before:

const name = 'Bob Hope'
const person = preval`
  const [first, last] = require('./name-splitter')(${name})
  module.exports = {first, last}
`

After (assuming ./name-splitter is a function that splits a name into first/last):

const name = 'Bob Hope'
const person = {first: 'Bob', last: 'Hope'}

import comment

Before:

import fileList from /* preval */ './get-list-of-files'

After (depending on what ./get-list-of-files does, it might be something like):

const fileList = ['file1.md', 'file2.md', 'file3.md', 'file4.md']

You can also provide arguments which themselves are prevaled!

Before:

import fileList from /* preval(3) */ './get-list-of-files'

After (assuming ./get-list-of-files accepts an argument limiting how many files are retrieved:

const fileList = ['file1.md', 'file2.md', 'file3.md']

preval.require

Before:

const fileLastModifiedDate = preval.require('./get-last-modified-date')

After:

const fileLastModifiedDate = '2017-07-05'

And you can provide some simple dynamic arguments as well:

Before:

const fileLastModifiedDate = preval.require(
  './get-last-modified-date',
  '../../some-other-file.js',
)

After:

const fileLastModifiedDate = '2017-07-04'

preval file comment (// @preval)

Using the preval file comment will update a whole file to be evaluated down to an export.

Whereas the above usages (assignment/import/require) will only preval the scope of the assignment or file being imported.

Before:

// @preval

const id = require('./path/identity')
const one = require('./path/one')

const compose = (...fns) => fns.reduce((f, g) => a => f(g(a)))
const double = a => a * 2
const square = a => a * a

module.exports = compose(square, id, double)(one)

After:

module.exports = 4

Exporting a function

If you export a function from a module that you're prevaling (whether using preval.require or the import comment), then that function will be called and whatever is returned will be the prevaled value.

It's important to know this if you want to have the prevaled value itself be a function:

Example:

// example-module.js
const fn = message => `The message is: ${message}`
module.exports = () => fn

Usage of preval:

const theFn = preval.require('./example-module.js')

Generated code:

const theFn = message => `The message is: ${message}`

Configure with Babel

Via .babelrc (Recommended)

.babelrc

{
  "plugins": ["preval"]
}

Via CLI

babel --plugins preval script.js

Via Node API

require('babel-core').transform('code', {
  plugins: ['preval'],
})

Use with babel-plugin-macros

Once you've configured babel-plugin-macros you can import/require the preval macro at babel-plugin-preval/macro. For example:

import preval from 'babel-plugin-preval/macro'

const one = preval`module.exports = 1 + 2 - 1 - 1`

You could also use preval.macro if you'd prefer to type less ๐Ÿ˜€

Examples

Notes

If you use babel-plugin-transform-decorators-legacy, there is a conflict because both plugins must be placed at the top

Wrong:

{
  "plugins": ["preval", "transform-decorators-legacy"]
}

Ok:

{
  "plugins": ["preval", ["transform-decorators-legacy"]]
}

FAQ

How is this different from 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 possible in the browser (or with prepack), but preval enables you to do this.

How is this different from webpack loaders?

This plugin was inspired by webpack's 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, 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.

Inspiration

I needed something like this for the glamorous website. I live-streamed developing the whole thing. If you're interested you can find the recording on my youtube channel (note, screen only recording, no audio).

I was inspired by the val-loader from webpack.

Related Projects

Other Solutions

I'm not aware of any, if you are please make a pull request and add it here!

Issues

Looking to contribute? Look for the Good First Issue label.

๐Ÿ› Bugs

Please file an issue for bugs, missing documentation, or unexpected behavior.

See Bugs

๐Ÿ’ก Feature Requests

Please file an issue to suggest new features. Vote on feature requests by adding a ๐Ÿ‘. This helps maintainers prioritize what to work on.

See Feature Requests

Contributors โœจ

Thanks goes to these people (emoji key):


Kent C. Dodds

๐Ÿ’ป ๐Ÿ“– ๐Ÿš‡ โš ๏ธ

Matt Phillips

๐Ÿ’ป ๐Ÿ“– โš ๏ธ

Philip Oliver

๐Ÿ›

Sorin Davidoi

๐Ÿ› ๐Ÿ’ป โš ๏ธ

Luke Herrington

๐Ÿ’ก

Lufty Wiranda

๐Ÿ’ป

Oscar

๐Ÿ’ป โš ๏ธ

pro-nasa

๐Ÿ“–

Sergey Bekrin


Mauro Bringolf

๐Ÿ’ป โš ๏ธ

Joe Lim

๐Ÿ’ป

Marcin Zielinski

๐Ÿ’ป

Tommy

๐Ÿ’ป

Matheus Gonรงalves da Silva

๐Ÿ“–

Justin Dorfman

๐Ÿ”

Andrew Rottier

๐Ÿ“–

Michaรซl De Boey

๐Ÿ’ป

Braydon Hall

๐Ÿ’ป

Jacob M-G Evans

๐Ÿ’ป

Juhana Jauhiainen

๐Ÿ’ป

Peter Hozรกk

๐Ÿ’ป

Michael Peyper

๐Ÿ’ป

Marcelo Silva Nascimento Mancini

๐Ÿ“– ๐Ÿ”Œ

Minh Nguyen

๐Ÿ’ป โš ๏ธ ๐Ÿš‡

This project follows the all-contributors specification. Contributions of any kind welcome!

LICENSE

MIT

babel-plugin-preval's People

Contributors

allcontributors[bot] avatar andreineculau avatar andrewmcodes avatar andrewrot avatar geovanisouza92 avatar infiniteluke avatar jdorfman avatar luftywiranda13 avatar marzelin avatar matheus1lva avatar mattphillips avatar maurobringolf avatar michaeldeboey avatar mpeyper avatar mrcsnm avatar nminhnguyen avatar obartra avatar sbekrin avatar siddharthkp avatar sorin-davidoi avatar souporserious avatar tleunen avatar xjlim avatar ykzts avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

babel-plugin-preval's Issues

add support for preval comments

There currently is no support to preval comments, which might be a useful approach to manage comment hints provided by other plugins.
I understand this project may have been frozen or something, but it would be nice to at least have some discussion in case someone forked it or want to start a new project similar to it.

Bug: throw Unexpected Name when pass string literal

  • babel-plugin-preval version: 5.0.0 (preval.macro 3.0.0)
  • node version: v14.16.1
  • npm (or yarn) version: 6.14.12

Relevant code or config

export const searchPosts = preval`
  const tool = require('../../graphql/utils');
  module.exports = tool.maxDepth("searchPosts", 2);
`

What happened:
The "searchPosts" supposed to be a string literal, but this is what happened

preval.macro: Syntax Error: Unexpected Name "searchPosts". Learn more: https://www.npmjs.com/package/preval.macro

Reproduction repository:
I'll provide it when needed

Usage with 'babel-plugin-module-resolver'

  • babel-plugin-preval version: 4.0.0
  • node version: 12.14.0
  • npm (or yarn) version: 6.13.4

Relevant code or config

// usage
const URLS = preval`
  const { pureFunc } = require("@my/aliased/path");
  const url1 = pureFunc(...args)
  const url2 = pureFunc(...args);
  module.exports = {url1, url2}
`;
// .babelrc.js
{
  plugins: [
  [
    'babel-plugin-module-resolver',
    {
      alias: {
        '@my': './some/rel/path',
      }
    }
  ],
  '@babel/plugin-proposal-nullish-coalescing-operator',
  '@babel/plugin-proposal-optional-chaining',
  IS_DEVELOPMENT && '@babel/plugin-transform-react-jsx-source',
  '@babel/plugin-proposal-class-properties',
  '@babel/plugin-syntax-dynamic-import',
  'preval'
].filter(Boolean),
...
}

What you did:
Attempted to use preval where the require path uses an alias.

What happened:

Error: /path/to/project/src/MyComponent/data.ts: Cannot find module '@my/aliased/path'
Require stack:
- /path/to/project/src/MyComponent/data.ts
- /path/to/project/node_modules/babel-plugin-preval/dist/helpers.js
- /path/to/project/node_modules/babel-plugin-preval/dist/index.js
- /path/to/project/node_modules/@babel/core/lib/config/files/plugins.js
- /path/to/project/node_modules/@babel/core/lib/config/files/index.js
- /path/to/project/node_modules/@babel/core/lib/index.js
- /path/to/project/scripts/make-server.ts
- /path/to/project/scripts/main.ts
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:797:15)
    at Function.Module._load (internal/modules/cjs/loader.js:690:27)
    at Module.require (internal/modules/cjs/loader.js:852:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/path/to/project/src/MyComponent/data.ts:2:32)
    at Module._compile (internal/modules/cjs/loader.js:959:30)
    at requireFromString (/path/to/project/node_modules/require-from-string/index.js:28:4)
    at requireFromString (/path/to/project/node_modules/babel-plugin-preval/dist/helpers.js:21:13)
    at getReplacement (/path/to/project/node_modules/babel-plugin-preval/dist/helpers.js:39:15)
    at PluginPass.TaggedTemplateExpression (/path/to/project/node_modules/babel-plugin-preval/dist/index.js:79:29) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/path/to/project/src/MyComponent/data.ts',
    '/path/to/project/node_modules/babel-plugin-preval/dist/helpers.js',
    '/path/to/project/node_modules/babel-plugin-preval/dist/index.js',
    '/path/to/project/node_modules/@babel/core/lib/config/files/plugins.js',
    '/path/to/project/node_modules/@babel/core/lib/config/files/index.js',
    '/path/to/project/node_modules/@babel/core/lib/index.js',
    '/path/to/project/scripts/make-server.ts',
    '/path/to/project/scripts/main.ts'
  ]
}

Problem description:
Looks like the application of the plugins is such that the babel-plugin-module-resolver plugin is not applying the transformations to the code that is being preevaluated. I know that there are lots of things to consider when possibly evaluating the string passed to preval, but I wasn't sure if this was something that's possible.

Suggested solution:
Seems out of scope of this project, but I can only fathom that the right way to get this to work would have the alias plugin be applied before the code is preval'd such that the relative path is available for the preval step.

My other thought is that this might have to be its own macro? Would definitely appreciate some pointers on how something like this would be accomplished. It seems like compromising the aliasing is not something that our project would be willing to do. Thank you for you time and this project.

Cheers!

Broken with @babel/preset-env

  • babel-plugin-preval version: 2.0.0
  • node version: 10.4.0
  • yarn version: 1.7.0

Relevant code or config

// file.js
module.exports = new RegExp("aaa", "gim");
preval.require('./file.js')
[
  "@babel/preset-env",
  {
    useBuiltIns: "usage",
    shippedProposals: true,
    modules: false,
    targets: {
      browsers: ["last 2 versions"]
    }
  }
]

What happened:

image

Reproduction repository: https://github.com/goodmind/preval-preset-env

Problem description: @babel/preset-env useBuiltIns: "usage" injects unnecessary polyfills

Suggested solution: none

[Request] - Mention a plugin interaction

Hello!
I've made some plugin for webpack that generates a C-Like macro. So, I've been using this plugin with babel-plugin-preval, and it has a great relationship with this plugin.

For instance, I could define a new macro called _FILENAME_NO_EXT: which would write the current filename without any extension.

DEFINE(_FILENAME_NO_EXT, () =>
{
   return preval`__filename.substring(__filename.lastIndexOf("/")+1, __filename.lastIndexOf("."))`
});

When this function is called anywhere, the output code would be the filename where this function is called, every compile time feature has much to gain from that as it is a simple text replace tool.

//index.ts

console.log(_FILENAME_NO_EXT()); //index

Hope you take a look and we could work in some more interactions for define_macro-loader

Additional usage: flow style comment

Hey cool project! ๐Ÿ˜„

I was thinking another usage could be to have flow (// @flow) style comments at the start of a file to be ran through preval.

That way the consumer of a file would not need to annotate an import. Instead a module would have the scope defined to be pre-evaluated, without the need to explicitly import babel-plugin-preval.

Example:

foo.js

// @preval
const fs = require('fs');
module.exports = fs.readFileSync(require.resolve('./foo.txt'), 'utf8');

//      โ†“ โ†“ โ†“ โ†“ โ†“ โ†“
module.exports = "Hello world!"

bar.js

const foo = require('./foo');

console.log(foo); // Hello world!

Does not work via Node API

  • @babel/core 7.13.14
  • babel-plugin-preval version: 5.0.0
  • node version: v14.10.1
  • npm version: 6.14.8

Relevant code or config

const code = `
const v = 1 + 2
module.exports = { v }
`

console.log(require('@babel/core').transformSync(code, {
  plugins: ['preval']
}).code)

What you did:

I'd like to use preval at runtime to optimize some functions in a longer running script.
For, this, I installed babel and preval as normal dependencies and ran the script above:

$ npm install --save @babel/core @babel/preset-env babel-plugin-preval
$ node prevaltest.js
const v = 1 + 2;
module.exports = {
  v
};

What happened:

The script has not been transformed as expected.

Can not see console log output

For example,

const deploy = preval`
const deploy = process.env.DEPLOY || "local";
console.log("Deploy target:", deploy);
module.exports = deploy;
`;

Usage with Vite?

I'm migrating a legacy React TypeScript project from Webpack to Vite. I have some pretty substantial preval code.

Vite uses Babel internally, so I think it should be possible to use this with Vite. Has anyone succeeded in getting it working?

Dynamic File inside folders not rendering with React and preval.macro

I am trying to build an app which will show list of items read from a folder inside my create-react-app and it will read and show the file inside the folder.

`import React ,{useState} from 'react'
import preval from 'preval.macro';
import '../index.css'

const components = preval
const fs = require('fs'); const files = fs.readdirSync('src/atoms'); module.exports = files;

const AtomList = () => {

const [newFileName, setNewFileName] = useState('avatar');


const fileUnderComponent = preval
    `   const fs = require('fs')
        const path = require('path');
        const file = fs.readFileSync('src/atoms/${newFileName}/${newFileName}.js');
        module.exports = file.toString();
    `;

const setNewComponent = (componentName) => {
    setNewFileName(componentName)
}

const eachAtom = (component) => {
    return (
        <ul><li className="list-item-group" onClick={() => setNewComponent(component)}>{component}</li></ul>
    )
}

return (
    <div>
        <div className="list-group inlineBlock atomList width20">
            <div>List of Reusable Components</div>
            {components.map((component, i) => {
                return eachAtom(component)
            })}
        </div>
        <div className="list-group inlineBlock atomDescription width80">
            {typeof fileUnderComponent === 'string' ? fileUnderComponent : null}
        </div>

    </div>
)

}

export default AtomList

`

In the above component, if i hardcode newFileName as 'avatar' the contents of the file renders but when i switch the components on clicking them the newFileName changes but fileUnderComponent doesn't render anything.

I think probably due to readFileSync operation which takes some time. I have tried putting it in setTimeout but no luck.

Where could i go wrong?

The automated release is failing ๐Ÿšจ

๐Ÿšจ The automated release from the main branch failed. ๐Ÿšจ

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. Iโ€™m sure you can fix this ๐Ÿ’ช.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the main branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those donโ€™t help, or if this issue is reporting something you think isnโ€™t right, you can always ask the humans behind semantic-release.


No npm token specified.

An npm token must be created and set in the NPM_TOKEN environment variable on your CI environment.

Please make sure to create an npm token and to set it in the NPM_TOKEN environment variable on your CI environment. The token must allow to publish to the registry https://registry.npmjs.org/.


Good luck with your project โœจ

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€

'preval can also handle some simple dynamic values as well' not working on webpack

Using:
"webpack": "^4.46.0",
"nuxt": "^2.15.8",
"babel-plugin-preval": "^5.0.0",

const locale = 'ru'

// @/langs/ru.js:
// // @preval
//
// module.exports = require('../tools/i18n').packs.ru
const langPack = require(`@/langs/${locale}.js`) // WORKS
//const langPack = preval`module.exports = require('../tools/i18n').packs.ru` // WORKS
//const langPack = preval`module.exports = require('../tools/i18n').packs.${locale}` // DOES NOT WORK

Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: ${project}/plugins/index.js: Unable to determine the value of your preval string
at PluginPass.TaggedTemplateExpression (${project}/node_modules/babel-plugin-preval/dist/index.js:72:17)

Conflict

Hi

If we use "babel-plugin-transform-decorators-legacy", there is a conflict, because both plugins must be placed at the top

decorators ok, preval not ok

[ "transform-decorators-legacy", "preval" ]

preval ok, decorators not ok
[ "preval", "transform-decorators-legacy" ]

Validate fails due to missing eslint plugins

  • babel-plugin-preval version: 1.3.2
  • node version: 8.1.4
  • npm (or yarn) version: 5.2.0 and 0.27.5

Relevant code or config

What you did:
Run npm start validate

What happened:

> [email protected] start /home/sorin/Repositories/babel-plugin-preval
> nps "validate"

nps is executing `validate`: node node_modules/concurrently/src/main.js --kill-others-on-fail --prefix-colors "bgBlue.bold,bgMagenta.bold,bgGreen.bold" --prefix "[{name}]" --names "lint,build,test" 'nps lint' 'nps build' 'nps test'
[lint] nps is executing `lint`: eslint .
[build] nps is executing `build`: node node_modules/rimraf/bin.js dist && babel --copy-files --out-dir dist --ignore __tests__ src
[test] nps is executing `test`: jest --coverage
[lint] 
[lint] Oops! Something went wrong! :(
[lint] 
[lint] ESLint couldn't find the plugin "eslint-plugin-jest". This can happen for a couple different reasons:
[lint] 
[lint] 1. If ESLint is installed globally, then make sure eslint-plugin-jest is also installed globally. A globally-installed ESLint cannot find a locally-installed plugin.
[lint] 
[lint] 2. If ESLint is installed locally, then it's likely that the plugin isn't installed correctly. Try reinstalling by running the following:
[lint] 
[lint]     npm i eslint-plugin-jest@latest --save-dev
[lint] 
[lint] If you still can't figure out the problem, please stop by https://gitter.im/eslint/eslint to chat with the team.
[lint] 
[lint] The script called "lint" which runs "eslint ." failed with exit code 1 https://github.com/kentcdodds/nps/blob/v5.4.0/other/ERRORS_AND_WARNINGS.md#failed-with-exit-code
[lint] nps lint exited with code 1
--> Sending SIGTERM to other processes..
[build] nps build exited with code null
[test] nps test exited with code null

Reproduction repository:

Problem description:
Running validate fails dues to missing eslint plugins.

Suggested solution:

Install "eslint-plugin-babel", "eslint-plugin-import", "eslint-plugin-jest".
I see eslint-config-kentcdodds, should these be added here or in that config?

Refactor away babel-core dependency

Due to kentcdodds/babel-plugin-macros#41 we want to refactor babel-core away from our dependencies:

  1. Remove babel-core from the package.json dependencies.
  2. Remove the require here and instead accept babel as a item in the options argument.
  3. Change this to babel and move the destructuring to a const on the next line.
  4. Pass babel to each use of getReplacement

I think that's it. Anyone wanna do that?

run without babel (webpack)

Hello,

This project looks amazing !
I was wondering if it could be used without babel.
I'm currently using webpack and trying to implement angular AOT. But this include some limitations that this project could solve.
But I need to preval only before aot is run and no other transformation. That's why I don't need babel process.

Thanks

Cannot do typeof preval

  • babel-plugin-preval version: 3.0.1
  • node version: 11.10.1
  • yarn version: 1.15.0

Relevant code or config

typeof preval === 'function' ? preval` \* *\ ` : {};

What you did: Run typeof against preval function.

What happened: Failed with the following error:
Error: babel-plugin-preval/macro: babel-plugin-preval/macro can only be used as tagged template expression, function call or JSX element. You tried UnaryExpression.

Reproduction repository: N/A

Problem description:

I had problems with preval on the SSR server (related to importing the package) so I just wanted to run it conditionally on the client side, however I can't do typeof to check if it exists.

Suggested solution:

I think preval is being overprotective and too limiting while it should let the language itself validate what operations are valid.

I found this logic here:

} else {
throw new Error(
`babel-plugin-preval/macro can only be used as tagged template expression, function call or JSX element. You tried ${
referencePath.parentPath.type
}.`,
)
}

Not possible to mock implementation of preval in tests

  • babel-plugin-preval version: 3.0.1
  • node version: 10.15.3
  • npm (or yarn) version: 1.13.0

Relevant code or config:

import React from 'react';
import { shallow } from 'enzyme';
import { BuildInfo } from './BuildInfo';
import preval from 'preval.macro';

jest.mock('preval.macro');

describe('<BuildInfo />', () => {
  test('renders successfully', () => {
    preval.mockImplementation(jest.fn().mockReturnValueOnce('ABC234'));
    const component = shallow(<BuildInfo />);
    expect(component).toMatchSnapshot();
  });
});

What you did:
Ran above test with jest.

What happened:

preval.macro: babel-plugin-preval/macro can only be used as tagged template expression, function call or JSX element. You tried MemberExpression. Learn more: https://www.npmjs.com/package/preval.macro

Problem description:

It's not possible to mock preval for snapshot tests. In my case, preval returns the current git commit hash which is not usable for snapshot tests.

Suggested solution:

It looks like extra code is in place to restrict how the function is called. Suggested solution is to update that to allow mocking preval in jest or other test frameworks.

Using preval without evaling code imported with require().default

  • babel-plugin-preval version: ^1.6.2
  • node version: v8.9.4
  • npm (or yarn) version: yarn v1.3.2

Relevant code or config

const myObject = preval`
result = {}
const fullPath = 'some/derived/path/to/file.js'
result[fullpath] = {
    js: require(fullPath).default,
}
`

Where the value of js is the require'd code to be eval'd in the running app.

What you did:

Ran a more complete example on multiple paths in an Array.reduce()

What happened:

ERROR in ./pages/utils/transitions.js
Module build failed: /Users/matthew.brookes/Projects/material-ui/docs/src/pages/utils/transitions/SimpleCollapse.js:1
(function (exports, require, module, __filename, __dirname) { import React from 'react';
                                                              ^^^^^^

SyntaxError: Unexpected token import
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:607:28)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)
    at Module.require (module.js:587:17)
    at require (internal/module.js:11:18)
    at reducer (/Users/matthew.brookes/Projects/material-ui/pages/utils/transitions.js:10:9)
    at Array.reduce (<anonymous>)
    at Object.<anonymous> (/Users/matthew.brookes/Projects/material-ui/pages/utils/transitions.js:15:29)
    at Module._compile (module.js:643:30)
    at requireFromString (/Users/matthew.brookes/Projects/material-ui/node_modules/require-from-string/index.js:28:4)
    at getReplacement (/Users/matthew.brookes/Projects/material-ui/node_modules/babel-plugin-preval/dist/get-replacement.js:18:13)
    at PluginPass.TaggedTemplateExpression (/Users/matthew.brookes/Projects/material-ui/node_modules/babel-plugin-preval/dist/index.js:56:27)
 @ multi ./pages/utils/transitions.js

Where:

/Users/matthew.brookes/Projects/material-ui/docs/src/pages/utils/transitions/SimpleCollapse.js

is the file being required

import React from 'react'

is the first line of that file.

/Users/matthew.brookes/Projects/material-ui/pages/utils/transitions.js

is the file containing preval.

Reproduction repository:

I don't have a minimal version to share, but you could

git clone clone https://github.com/mui-org/material-ui.git
yarn
yarn start

Then replace pages/utils/transitions.js with this: https://gist.github.com/mbrookes/e933031d378ce7169d9f21a774330a11

Problem description:

preval evals code imported with require().default

Thanks! ๐ŸŒŸ

crash on file with only comments

  • babel-plugin-preval version: 1.4.2

I have a file that was commented out in its entirety, and then babel-plugin-preval crashes with

TypeError: src/aws-elb.js: Cannot read property 'leadingComments' of undefined
    at PluginPass.Program (/Users/andrei/git/firecloud/aws-cfn-util-firecloud/node_modules/babel-plugin-preval/dist/index.js:26:41)
    at newFn (/Users/andrei/git/firecloud/aws-cfn-util-firecloud/node_modules/babel-traverse/lib/visitors.js:276:21)
    at NodePath._call (/Users/andrei/git/firecloud/aws-cfn-util-firecloud/node_modules/babel-traverse/lib/path/context.js:76:18)
    at NodePath.call (/Users/andrei/git/firecloud/aws-cfn-util-firecloud/node_modules/babel-traverse/lib/path/context.js:48:17)
    at NodePath.visit (/Users/andrei/git/firecloud/aws-cfn-util-firecloud/node_modules/babel-traverse/lib/path/context.js:105:12)
    at TraversalContext.visitQueue (/Users/andrei/git/firecloud/aws-cfn-util-firecloud/node_modules/babel-traverse/lib/context.js:150:16)
    at TraversalContext.visitSingle (/Users/andrei/git/firecloud/aws-cfn-util-firecloud/node_modules/babel-traverse/lib/context.js:108:19)
    at TraversalContext.visit (/Users/andrei/git/firecloud/aws-cfn-util-firecloud/node_modules/babel-traverse/lib/context.js:192:19)
    at Function.traverse.node (/Users/andrei/git/firecloud/aws-cfn-util-firecloud/node_modules/babel-traverse/lib/index.js:114:17)
    at traverse (/Users/andrei/git/firecloud/aws-cfn-util-firecloud/node_modules/babel-traverse/lib/index.js:79:12)

Closure context lost

If there is:

import preval from 'babel-plugin-preval/macro';

module.exports = preval`
  const _ = require('lodash');
  const arr = ['1', '2', '3'];

  module.exports = _.zipObject(arr, arr.map(variableName => loader => loader.load(variableName)));
`;

The imported 1 will be loader => loader.load(variableName)
Where variableName is a missing variable, will throw an error variableName is not defined

Even variableName => loader => loader.load(\`\${variableName}\`)) is not working.
Then imported 1 will be loader => loader.load(`${variableName}`)

Exporting a certain combination of functions yields SyntaxError

  • babel-plugin-preval version: 1.3.2
  • node version: 8.1.4
  • npm (or yarn) version: 0.5.2 and 0.27.5

Relevant code or config

// @preval

const emojione = require('emojione');

module.exports = {
  convert: emojione.convert,
  shortnameToUnicode: emojione.shortnameToUnicode,
};

What you did:
Ran babel file.js

What happened:

SyntaxError: file.js: Unexpected token, expected , (30:5)

Problem description:

I am trying to do some manual tree shaking for EmojiOne (since it is not exported as a CommonJS module). What is interesting is that if you leave out either one of the exports it works fine.

Suggested solution:
None so far.

[Question] How to use --experimental-modules node mjs module

Thank you for this wonderful library.
I have code need to preval, but they are written in es6 module
Needs to be executed with --experimental-modules arguments.
Can preval handle this? (I just try, it didn't work).
Without preval, I have to configure my project like this:

{
  "build": "node --experimental-modules src/main.mjs && react-scripts build"
}

Which is also acceptable, but if preval supports it, it will be alot convinent.

Thank you for listening.

Cannot read property 'some' of undefined (while running with babel-node/babel-cli)

  • babel-plugin-preval version: 1.2.0
  • node version: 6.7.0
  • yarn version: 0.23.2

Relevant code or config

package.json scripts

{
    "scripts": {
        "start": "npm-run-all --parallel test:watch open:src lint:watch",
        "open:src": "babel-node tools/srcServer.js", // note this (babel-node)
    }
}

.babelrc

{
    "presets": ["react", "stage-1"],
    "env": {
        "development": {
            "plugins": ["preval"],
            "presets": ["env", "react-hmre"]
        },
        "production": {
            "presets": [
                [
                    "env",
                    {
                        "es5": {
                            "modules": false
                        }
                    }
                ]
            ],
            "plugins": [
                "transform-react-constant-elements",
                "transform-react-remove-prop-types"
            ]
        },
        "test": {
            "presets": ["env"]
        }
    }
}

tools/srcServer:
https://github.com/coryhouse/react-slingshot/blob/770e88e2bd32067acb59cf3c62e0f051f3621a42/tools/startMessage.js

What you did:
yarn start
Running babel-node (babel-cli) on a node-script with preval as plugin in .babelrc throws an error.

What happened:

C:\Users\PA\Desktop\react-playground\preval-issue (master) ([email protected])
ฮป yarn start
yarn start v0.23.2
$ npm-run-all --parallel start-message

> [email protected] start-message C:\Users\PA\Desktop\react-playground\preval-issue
> babel-node tools/startMessage.js

C:\Users\PA\Desktop\react-playground\preval-issue\node_modules\babel-register\node_modules\babel-core\lib\transformation\file\index.js:590
      throw err;
      ^

TypeError: C:/Users/PA/Desktop/react-playground/preval-issue/tools/startMessage.js: Cannot read property 'some' of undefined
    at leadingComments (C:\Users\PA\Desktop\react-playground\preval-issue\node_modules\babel-plugin-preval\dist\index.js:66:32)
    at C:\Users\PA\Desktop\react-playground\preval-issue\node_modules\babel-plugin-preval\dist\index.js:193:14
    at Array.every (native)
    at looksLike (C:\Users\PA\Desktop\react-playground\preval-issue\node_modules\babel-plugin-preval\dist\index.js:189:35)
    at C:\Users\PA\Desktop\react-playground\preval-issue\node_modules\babel-plugin-preval\dist\index.js:195:48
    at Array.every (native)
    at looksLike (C:\Users\PA\Desktop\react-playground\preval-issue\node_modules\babel-plugin-preval\dist\index.js:189:35)
    at C:\Users\PA\Desktop\react-playground\preval-issue\node_modules\babel-plugin-preval\dist\index.js:195:48
    at Array.every (native)
    at looksLike (C:\Users\PA\Desktop\react-playground\preval-issue\node_modules\babel-plugin-preval\dist\index.js:189:35)

Reproduction repository:
coryhouse/react-slingshot

  • clone
  • yarn run setup (takes about 2 min)
  • yarn add --dev babel-plugin-preval
  • add "preval" to babel.env.development.plugins[] in package.json
  • yarn start

Problem description:
argument comments is undefined here: /src/index.js#L62 but still tries to call function some.

Suggested solution:
make sure comments is not undefined before calling property some.
But if comments is undefined what should we return? false?

Issue with JSPM and SystemJS

  • babel-plugin-preval version: v1.5.0
  • JSPM version: 0.17.0-beta-42

What you did:

Installed prevel with JSPM:

jspm install preval=npm:babel-plugin-preval --dev

What happened:

It resulted in error

err  Error on translate for kotsu/main.js at file:///J:/Work/Kotsu/github/source/scripts/main.js
  (SystemJS) ENOENT: no such file or directory, open 'J:\Work\Kotsu\github\${path.node.source.value}'
  Error: ENOENT: no such file or directory, open 'J:\Work\Kotsu\github\${path.node.source.value}'
  Error loading J:/Work/Kotsu/github/${path.node.source.value} as "${path.node.source.value}" from J:/Work/Kotsu/github/jspm_packages/npm/[email protected]/dist/index.js

Problem description:

It seems that preval doesn't work well with JSPM and SystemJS.

In this issue jspm/jspm-cli#2335 described few issues, that arises when prevel used with JSPM. Usually babel plugins working out of box with JSPM or SystemJS, but not in this case.

Most of described issues aren't that critical and workaroundable (though, it still a mystery to me are they caused by prevel or JSPM), except the last one, related to inability of JSPM locate a file (see error above).

Suggested solution:

The source of the issue seems to be this line

var mod = require('${path.node.source.value}');
with pseudo-template literal:

'${path.node.source.value}'

Seems like JSPM is unable to handle it because to SystemJS it just another string, not a template literal.

code transpilation is not performed for imported modules when prevaling with template literals

  • babel-plugin-preval version: ^1.6.3
  • node version: ^9
  • npm (or yarn) version: ^1

Great tool, thanks for it. There's one thing though: when the code to be prevaled in template tags requires a module, that module won't be transpiled by babel. For example, this code that prerenders a react element:

const markupForElement = preval`
   const render = require("react-dom/server").renderToStaticMarkup;
   const reactElement = require("./reactElement");
   module.exports = render(reactElement);
`

will fail with error:

Module build failed: .../reactElement.js:2
const reactElement = <div>Hello from React Element</div>;
                     ^

SyntaxError: Unexpected token <

even though react preset is added to babel configuration.

The simplest solution is to add require("babel-register"); at the top of a template literal. However, it would be nice if this package could handle this automatically.

Suggested solution:
Prepend transpiled with "require("babel-register");\n" before passing it to requireFromString at

const val = requireFromString(transpiled, filename)

How do you accept arguments

In the README.md you showed that it is possible to pass arguments to preval, is this possible, and how it works?

import fileList from /* preval(3) */ './get-list-of-files'

[question] Using objects as template placeholders

Hi,

I was trying out preval with NextJS to inline my data during build time.

This is my code:

static async getInitialProps() {
    const { data } = await Axios.get(
      "http://localhost:3100/graphql?query={ articles{ name slug } }"
    );
// data.data is an object
    const actualData = preval`
    const allArticles = ${data.data}
    module.exports = allArticles
    `;
    console.log(actualData);
    return { data };
  }

When I console log it, it returns an empty object. Am I doing something wrong here?

Non-default imports/exports are not working properly

  • babel-plugin-preval version: 1.4.4
  • node version: 8.4.0
  • yarn version: 0.27.5

Relevant code or config

import { readdirSync } from 'fs';
import { join } from 'path';

const ROMS_PATH = join(__dirname, '../roms');

export const ROM_FILE_EXTENSION = '.ch8';

const ROM_CATEGORIES = ['demos', 'games', 'programs'];

export default ROM_CATEGORIES
  .map(category => [
    category,
    readdirSync(join(ROMS_PATH, category))
      .filter(fileName => fileName.endsWith(ROM_FILE_EXTENSION)) // Keep ROMs only
      .map(fileName => fileName.slice(0, -ROM_FILE_EXTENSION.length)), // Remove file extension
  ]);

What you did:

Trying to use non-default ES2015+ exports.

import ROMList, { ROM_FILE_EXTENSION  } from /* preval */ './get-list-of-roms';

console.log(ROMList); // Working
console.log(ROM_FILE_EXTENSION); // undefined

What happened:

Nothing got assigned to the non-default exported constant's value.

Problem description:

Non-default imports/exports are not working properly when using a /* preval */ import comment.

Workign with TypeScript

  • babel-plugin-preval version: 5.0.0
  • node version: 14.0
  • npm (or yarn) version: 6.14.13

Relevant code or config

{preval`translate('HOME_BUTTON')`}

What you did:
Followed the README for installation and usage.
What happened:
Get an error

Type error: Cannot find name 'preval. Did you mean 'eval'?

Problem description:
Seems like typescript fails before babel has a chance to run.
Suggested solution:
Disable typescript ? ๐Ÿค”

[discussion]: update ci config and some other configs

Current behavior:

  • babel-preset-env targets node v4.5. See .babelrc
  • Travis runs only on node v8. See .travis.yml
  • There is no engines field specified in package.json

Problem description:

I think we need to make sure we run the build/test/etc on some specific environments. So that we can avoid publshing a new version of babel-plugin-preval that not only compatible with node v8 and npm v5 (node v8 bundles with npm 5)

Suggested solution:

  • Update .travis.yml to make Travis runs on multiple node version (e.g. v4, v6, v8)
  • Add engines field in package.json so that it can show warnings when users try to install this package in unsupported npm or node versions
  • And maybe if we decide to also run Travis with node v4 (it ships with npm v2), we can force Travis to install npm@^3 by specifying it in before_install.

What do you think @kentcdodds? I can make a PR if you agree with this

Simplify function injection

So I was trying to use preval to insert functions into my code before run time. What I thought was going to be quite trivial, turned out to be a bit tricky. In order to insert functions, preval implicitly requires you to wrap your exports in an object.

Example function:

function doThing(message) { return message + ' a thing'; }
module.exports = { doThing }; // You must wrap it here [see explanation A below]

Usage of preval:

const doThing = preval.require('./doDigest.js').doThing; // pull out function from object
// In order to insert a function, you must wrap it in an object and then extract it

Generated code:

var doThing = {
  "doThing": function doThing(message) {
    return message + ' a thing';
  }
}.doThing;

explanation A

Preval then creates an object with our function inside. This is a bit funky for users. If you attempt to do this without wrapping your exports as an object, preval will fail to inject the function with the following behavior:

confusing failed scenario to insert function

Example function:

function doThing(message) { return message + ' a thing'; }
module.exports = doThing; // Omission of object wrapper

Usage of preval:

const doThing = preval.require('./doDigest.js');

Generated code:

var doThing = "undefined a thing";

Suggestion

A.) To make this easier for users to insert functions into their code, you may want to consider the way preval requires modules.
B.) Add an example to the README.md that illustrates how this is done.

Preval fails when using imported vars

  • babel-plugin-preval version: 1.5.0
  • node version: 6.11.2
  • npm (or yarn) version: 3.10.10

Works:

let foo = 'bar';

let result = preval`
    module.exports = "${ foo }";
`;

Fails with Unable to determine the value of your preval string:

import { foo } from './foo';

let result = preval`
    module.exports = "${ foo }";
`;

What you did:

Tried to include an imported variable into a preval string

What happened:

Error thrown:

internal/streams/legacy.js:59
      throw er; // Unhandled stream error in pipe.
      ^
Error: ./src/components/button/templates/component/style/base.js
Module build failed: Error: /Users/dbrain/paypal-checkout/src/components/button/templates/component/style/base.js: Unable to determine the value of your preval string
    at PluginPass.TaggedTemplateExpression (/Users/dbrain/paypal-checkout/node_modules/babel-plugin-preval/dist/index.js:54:17)
    at newFn (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/visitors.js:276:21)
    at NodePath._call (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/path/context.js:76:18)
    at NodePath.call (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/path/context.js:48:17)
    at NodePath.visit (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/path/context.js:105:12)
    at TraversalContext.visitQueue (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/context.js:150:16)
    at TraversalContext.visitSingle (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/context.js:108:19)
    at TraversalContext.visit (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/context.js:192:19)
    at Function.traverse.node (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/index.js:114:17)
    at NodePath.visit (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/path/context.js:115:19)
    at TraversalContext.visitQueue (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/context.js:150:16)
    at TraversalContext.visitMultiple (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/context.js:103:17)
    at TraversalContext.visit (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/context.js:190:19)
    at Function.traverse.node (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/index.js:114:17)
    at NodePath.visit (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/path/context.js:115:19)
    at TraversalContext.visitQueue (/Users/dbrain/paypal-checkout/node_modules/babel-traverse/lib/context.js:150:16)
 @ ./src/components/button/templates/component/style/index.js 5:12-29
 @ ./src/components/button/templates/component/template.js
 @ ./src/components/button/templates/component/index.js
 @ ./src/components/button/templates/index.js
 @ ./src/components/button/component.jsx
 @ ./src/components/button/index.js
 @ ./src/components/index.js
 @ ./src/interface.js
 @ ./src/index.js
 @ ./src/load.js

Support for inlining babel options

First of all, thanks for creating this amazing piece of work. I'm working on using this plugin for evaling css styles in tagged template literals on compile time, we have working prototype and we would like to give the users option to specify different babel config that will be used in evaling.

For instance, with webpack, currently the user cannot use modules: false with for instance babel-preset-es2015 in .babelrc.

I'm happy to create and submit a PR to support this, but I need to know if you want to have it and collect some feedback before starting the work.

Here are the proposed additions:

preval tagged template literal

A new function preval.withOptions, which would accept a stringified babel options, it would be then parsed with JSON.parse:

const greeting = preval.withConfig('{"presets":["es2015"],"plugins":["myPlugin"]}')`
  const fs = require('fs')
  module.exports = fs.readFileSync(require.resolve('./greeting.txt'), 'utf8')
`

import comment

A support for optional stringified babel options, after preval keyword:

import fileList from /* preval {"presets":["es2015"],"plugins":["myPlugin"]} */ './get-list-of-files'

This way, it would still be possible to pass arguments:

import fileList from /* preval(3) {"presets":["es2015"],"plugins":["myPlugin"]} */ './get-list-of-files'

preval.require

Either accept a option as an object (or string) as a second argument:

const fileLastModifiedDate = preval.require('./get-last-modified-date', { presets: ['es2015'] });

or expose a new function requireWithOptions, which would accept a 2nd argument:

const fileLastModifiedDate = preval.requireWithOptions('./get-last-modified-date', { presets: ['es2015'] });

preval file comment

A support for stringified babel options after preval keyword:

// @preval {"presets":["es2015"],"plugins":["myPlugin"]}

const id = require("./path/identity")
const one = require("./path/one")

const compose = (...fns) => fns.reduce((f, g) => a => f(g(a)))
const double = a => a * 2
const square = a => a * a

module.exports = compose(square, id, double)(one)

What do you think? Do you like it or not (please comment why) or do you have a better idea/solution?

Like I said, I'm happy to prepare a PR for this.

[Suggestion] Implicit `module.exports ` if not specified

I think implicitly adding module.exports = at the beginning of a string where it's not specified would go a long ways towards reducing verbosity.

A possible solution would simple to be check if /module\.exports\w*=/ is present in the string provided. It wouldn't catch all cases, but it also wouldn't introduce any false positives.

Writing preval files in TypeScript

When using // @preval at the top of the file, it's first evaluated in Node.js. This means that TypeScript has no idea what's going on. If I leave these files as vanilla JS (.js) it's okay (the import gets an any type in TS), but then we don't get the advantages of TypeScript.

Can I write preval files themselves in TypeScript? Maybe with ts-node?

Ignoring preval in node_modules

I have a node_module with preval in it, but this is ignoring it. It only works when preval is used outside of node_modules.

Feature request: reusable prevals

Just wanted to make a quick note of this idea.

Would be really cool if we could define a re-usable preval in code. Right now I have:

export let componentStyle = preval`
    module.exports = require('node-sass').renderSync({
        data: \`${ style }\`
    }).css.toString();
`;

It would be awesome if I could break this out or alias it into a reusable prevalSass or something like that:

let prevalSass = prevalAlias`
    module.exports = require('node-sass').renderSync({
        data: \`$input`
    }).css.toString();
`;

export let componentStyle = prevalSass`${ style }`;

Not really attached to any particular semantics for this -- just like the idea of being able to write little reusable preval macros.

Cannot read property 'leadingComments' of undefined

  • babel-plugin-preval version: 1.4.1
  • node version: 7.10.0
  • npm (or yarn) version: 4.2.0

What you did:

Added an empty entry point to my webpack config (using babel-loader and babel-plugin-preval)

What happened:

Webpack failed to compile with the following error:
Cannot read property 'leadingComments' of undefined

Adding comments to the file does not fix. Adding any JavaScript code to the file fixes the issue.

SyntaxError: Expecting Unicode escape sequence \uXXXX.

  • babel-plugin-preval version: v5.0.0
  • node version: v14.17.0
  • npm (or yarn) version: npm v6.14.13

Relevant code or config

import tailwindConfig from /* preval */ '../tailwind.config';

export const extractedTailwindConfig = tailwindConfig;
export const extractedTailwindTheme = extractedTailwindConfig.theme;

What you did: Suddenly appeared after doing an npm ci

What happened:

We're utilizing babel-plugin-react in our nextjs project as a way to easily extract tailwind theme config variables. However, after doing an npm ci this issue suddenly appeared.

image

I'm currently utilizing windows and it seem to flag out the macOS' /r. Removing all the new line and sticking everything together seem to fix it.

Any help would be appreciated as we're currently lost with this issue

"preval file comment" method has no effect on modules that use Strict Mode

  • babel-plugin-preval version: 1.6.3
  • node version: 8.5.0
  • npm (or yarn) version: 5.3.0
  • (also maybe relevant, but probably not) @babel/core version: 7.0.0-beta.38

What you did: Tried to use the "preval file comment" method on a Strict Mode file, e.g.:

// @preval
'use strict';
// ...

What happened: The file did not get "prevaled". There was no error or warning.

Reproduction repository: https://github.com/zenflow/preval-use-strict-bug

Problem description: As titled, "preval file comment" method has no effect on modules that use Strict Mode

Suggested solution: No idea... make it work? : D

Thanks @kentcdodds for your work on this and all your other brilliant innovations!

How could I import multiple files with this?

Very interesting plugin! I have an application that allows for plugins as separate NPM packages. Right now, users have to add these manually to a file, first importing them, and then adding them to an array. Example code looks like this:

import acInduction from 'ac-induction';
import acBrainstorm from 'ac-brainstorm';
import acChat from 'ac-chat';

export const activityTypes: Array<ActivityPackageT> = [
  acInduction,
  acBrainstorm,
  acChat
].map(x => Object.freeze(x));

I would love to enable users to skip this step, by reading all ac-* packages from the package.json and automatically generating this code, and preval seems like a perfect candidate. However, I couldn't quite figure out how to do this - I can figure out how to get a list of packages, but how to generate the code? Do I build up a string and then eval it, or how can I generate it?

I realize this is not a traditional issue, but I'd really appreciate your feedback. Thanks!

(repo: https://github.com/chili-epfl/FROG)

suggestion - rename to just 'preval'

the babel-plugin- prefix is mostly inertia from the rest of the ecosystem, and creates dissonance especially when used with babel-macros. just preval would be nice, I think? the module name is available too, so do consider.

ReferenceError: Can't find variable: preval (React Native app)

  • babel-plugin-preval version: 5.1.0
  • node version: 16.12.0
  • npm (or yarn) version: 8.4.1

Relevant code or config

const gitHash = preval`
  import GitInfo from 'react-git-info/macro';
  gitInfo = GitInfo();
  module.exports = gitInfo.commit.shortHash
`

My babel.config.js file:

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: ['babel-plugin-preval']
}

What you did: I'm trying to use preval to get the git hash and have it displayed in the app.

What happened:

ReferenceError: Can't find variable: preval

I'm not sure if there's any additional steps I need to take to have this work in React Native.

Customize string quotation style

  • babel-plugin-preval version: 1.4.2
  • node version: v7.8.0
  • npm (or yarn) version: 4.2.0

Relevant code or config:

Before:

const renderTemplate = (one, two) => `3 === ${one + two}`

After:

const renderTemplate = (one, two) => preval`
  module.exports = require('fs').readFileSync('./template.js', 'utf8')
`
3 === ${one + two}

What you did:

I moved one template string that I had on a file to another file, and replaced with a preval to read that file.

What happened:

It replaced with a string quoted with double quotes.

Problem description:

I was expecting to keep the backticks, allowing babel to transpile it correctly later on the pipeline.

Suggested solution:

There is a way to customize quotation style or instruct preval which AST string to render?

How to force recompile?

  • babel-plugin-preval version: 1.4.1
  • node version: 8.1.3
  • npm (or yarn) version: npm 5.2.0

Relevant code or config

const result = preval`
  const fs = require('fs');
  const path = require('path');
  const content = fs.readFileSync(path.join(__dirname, 'file.md'));
  module.exports = content.toString();
`;

console.log(result);

What you did: I ran the code above, to export contents of file.md.

What happened: when I modify file.md the result of preval didn't change when I tried to compile it again. Maybe I'm missing something?

Reproduction repository: demo

Problem description: preval probably doesn't see the reason to recompile because its tagged template literal didn't change.

Suggested solution: I don't know. ๐Ÿ˜…

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.