Giter Site home page Giter Site logo

babel-plugin-import-glob's Introduction

babel-plugin-import-glob

Babel plugin to enable importing modules using a glob pattern. Tested with Node.js 4 and above.

Installation

npm install --save-dev babel-plugin-import-glob

Then add import-glob to your .babelrc file, like:

{
  "plugins": ["import-glob"]
}

Usage

This plugin is useful if you have multiple modules but you don't want to import them one at a time.

Maybe you're using the handlebars-inline-precompile plugin and are putting your modules in a templates directory. Or you need to dynamically reference one out of several classes and don't want to maintain the lookup by hand. Perhaps you need to load multiple modules for their side-effects and wish to simply add them to a directory without additional work. If so, this plugin is for you!

Of course in the vast majority of cases you should just use normal import statements. Don't go overboard using this plugin.

You can import the default members of any matching module. Let's say you have a directory layout like this:

  • index.js
  • templates/main.handlebars.js
  • templates/_partial.handlebars.js

In index.js you can write:

import { main, _partial } from './templates/**/*.handlebars.js'

You can add an optional glob: prefix:

import { main, _partial } from 'glob:./templates/**/*.handlebars.js'

You can alias members:

import { main, _partial as partial } from './templates/**/*.handlebars.js'

Or import all matches into a namespace object:

import * as templates from './templates/**/*.handlebars.js'
// Provides `templates.main` and `templates._partial`

Note that you cannot import the default from the glob pattern. The following won't work and throws a SyntaxError:

import myTemplates from './templates/**/*.handlebars.js' // This will throw a SyntaxError

You can load modules for their side-effects though:

import './modules-with-side-effects/*.js'

Glob patterns

The plugin uses the glob package. Please refer to its documentation regarding the pattern syntax.

The glob pattern must be relative. It must start with ./ or ../. A SyntaxError is thrown otherwise.

Import members

Identifiers are generated for all matches using the dynamic portions of the pattern. File-separators in the resulting strings are replaced by dollar signs. The strings are then converted into identifiers.

A valid identifier cannot always be generated. If that's the case a SyntaxError is thrown with more details. Similarly multiple matches may result in the same identifier. This also results in a SyntaxError being thrown.

For the ./templates/**/*.handlebars.js example above the matches are:

  • ./templates/main.handlebars.js
  • ./templates/_partial.handlebars.js

The dynamic portions are main and _partial. These are valid identifiers and therefore used as the import members.

A SyntaxError is throw when importing a member that does not correspond to a match:

import { doesNotExist } from './templates/**/*.handlebars.js' // This will throw a SyntaxError

Here's an overview of how the members are determined for additional matches:

Match Result Reason
./templates/terms-and-conditions.handlebars.js termsAndConditions The - cannot be used in the identifier so it's removed. The following character is uppercased
./templates/blog/footer.handlebars.js blog$footer The blog directory is captured by the ** expression in the pattern. It is joined with the footer name using a dollar sign
./templates/-main.handlebars.js SyntaxError The - is removed, resulting in the same identifier as for main.handlebars.js
./templates/new.handlebars.js _new new is a reserved word so it's prefixed with an underscore
./templates/blog/new.handlebars.js blog$new Even though new is a reserved word, it's combined with blog$ so no prefix is necessary
./templates/404.handlebars.js _404 Identifiers can't start with digits so it's prefixed with an underscore
./templates/error-pages/404.handlebars.js errorPages$404 Now that 404 is combined with errorPages$ it no longer needs to be prefixed
./templates/πŸ™Š.handlebars.js SyntaxError No identifier can be generated for πŸ™Š

Brace expansions are not considered to be a dynamic portion of the pattern. Given the pattern ./templates/{blog,error-pages}/*.handlebars.js:

Match Result
./templates/blog/footer.handlebars.js footer
./templates/error-pages/404.handlebars.js _404

Use parentheses patterns instead, e.g. ./templates/{@(blog),@(error-pages)}/*.handlebars.js:

Match Result
./templates/blog/footer.handlebars.js blog$footer
./templates/error-pages/404.handlebars.js errorPages$404

babel-plugin-import-glob's People

Contributors

greenkeeper[bot] avatar greenkeeperio-bot avatar lukescott avatar novemberborn 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

Watchers

 avatar  avatar  avatar

babel-plugin-import-glob's Issues

import named exports from pattern matches

Hi, thanks for the really helpful plugin.

i cannot however import named exports from a module file. The plugin only imports the default export.

example:

//cool.module.js
export const awesome = 'yay'
export default 'not so yay'
//index.js
import { awesome } from './**/*.module.js'
//Syntax error: Could not match import 'watchers' to a module. Available members are 'cool'

this would import the default import:

//index.js
import * as default from './**/*.module.js'
//default === 'not so yay'

Win & Linux importing.

So on windows the importing looks like this if i have the following directory structure:


- source/
  - app/
       -controllers/
            - a.js
            - b.js
            - c.js

import * as whatever from "app/**/*.js";

I receive an object that looks like this:
controllersa, controllersb, contorllersc ...

however on linux the output is
controllers$a, controllers$b, controllers$c, ...

I am not sure what is the reason behind this, but is there a way with your plugin to have the import mappings work such as

whatever.controllers.a 
whatever.controllers.b
whatever.controllers.c

or something similar?

pls plugin eslint

message: ''glob:routes' should be listed in the project's dependencies. Run 'npm i -S glob:routes' to add it (import/no-extraneous-dependencies)'at: '2,1' source: 'eslint'

How to import inside a function?

I need to convert the following into the appropriate syntax

if (module && module.hot)
    module.hot.accept('./reducers', () =>
      store.replaceReducer(nextRootReducer = require('./reducers').default)
    );

nothing i've tried has worked so far

Are you using some sort of cache?

For some reason, when I add a new file in my folder (note that it is inside a node_modules folder), on rebuild it's not detected. For some reason I need to change the glob (for instance switch between
whatever/* and whatever/*.js).
So is there some sort of cache in your implementation that could cause that?
The bug happens with webpack and babel on my project. I don't really have time to create a standalone reproduce of the bug, but I just like to understand what might be causing it.

Support globs inside a node module folder

We have a need to import all files in a folder that exist in a child installed node module.

We expect this...

import intlMessages from '@scopeName/packageName/intl/*.json';

...to resolve to here...

currentWorkingDirectory/node_modules/@scopeName/packageName/intl/*.json

...but instead, it tries to resolve to here...

currentWorkingDirectory/sourceFilePath/@scopeName/packageName/intl/*.json

...which of course breaks because the path doesn't exist.

One simple fix might be to do the following in index.js...

let files = glob.sync(pattern, {strict: true, nodir: true});
if (files.length === 0) {
  pattern = 'node_modules/' + path.node.source.value;
  files = glob.sync(pattern, {strict: true, nodir: true});
}

I've tested this locally and it appears to work against relative paths, regular node module paths, and scoped npm package paths.


  1. I'm happy to submit a PR if you don't have time to make this change. Would you consider a PR if I submit one?
  2. Is there anything else we'd need to test?

Thanks!

@jhicken Thanks for the help digging into this issue!

Export syntax

Love this plugin! Would be great to allow export syntax. Eg:

export { foo, bar } from 'glob:*';

Common suffix

It looks like this plugin strips a "common prefix" and "common extension". This works well if your file naming conventions use . for a common suffix, such as in your example .handlebars.js. However, if you prefer to use - or _ instead, you end up with the common bit in the identifier.

It looks like this project uses two custom dependencies:

"common-extname": "^1.0.0",
"common-path-prefix": "^1.0.0",

So changing this becomes a bit tricky. Do I need to add a third common-path-suffix repo?

I think a common suffix would probably be more helpful, as the common suffix will likely be in the pattern anyway. Of course there could be a configuration option to toggle the behavior.

Pathing issues?

Awesome module but I'm having a bit of trouble getting it working. I was using glob before like this:

const files = glob.sync(./dist/api/**/*[Controller].js);

and I converted it to your code like:

import * as filesz from 'glob:./dist/api/**/*[Controller].js';

but the result is this from the console:

info: import globs {}
info: globs [ './dist/api/ApplicationController.js',
  './dist/api/RecordController.js',
  './dist/api/SearchController.js' ]

Your exports are pretty specific to your use case, I think it could benefit from making it more generic. Also you don't really explain the difference between what 'main' and '_partial' is. Is partial the 'resolved' file? If so I'd recommend making a separate extension for that.

also would be cool to see integration with this: https://github.com/tleunen/babel-plugin-module-alias

An in-range update of codecov is breaking the build 🚨

Version 2.3.0 of codecov just got published.

Branch Build failing 🚨
Dependency codecov
Current Version 2.2.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As codecov is β€œonly” a devDependency of this project it might not break production or downstream projects, but β€œonly” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this πŸ’ͺ

Status Details
  • ❌ continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Commits

The new version differs by 6 commits.

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

globstar not finding first level files

Hi

My file structure is as following:

src
 |- root.js
 |- components
   |- foo.js 
   |- bar.js
   |- baz
    |- baz.js
    |- baz.css

In root.js I use the following import:

import * as Components from "./components/**/*.js";

which partially works, as Components only contains baz.js.

I would expect foo.js and bar.js to also be imported.

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.