GithubHelp home page GithubHelp logo

babel-plugin-wildcard's Introduction

babel-plugin-wildcard

Allows you to import all files from a directory at compile-time.

Installation

$ npm install babel-plugin-wildcard

Usage

Via .babelrc (Recommended)

.babelrc

{
  "plugins": ["wildcard"]
}

Via CLI

$ babel --plugins include script.js

Via Node API

require('babel').transform('code', {
  plugins: ['wildcard']
});

Example

With the following folder structure:

|- index.js
|- dir
    |- a.js
    |- b.js
    |- c.js

the following JS:

import * as Items from './dir';

will be compiled to:

const Items = {};
import _wcImport from "./dir/a";
Items.A = _wcImport;
import _wcImport1 from "./dir/b";
Items.B = _wcImport1;
import _wcImport2 from "./dir/c";
Items.C = _wcImport2;

meaning you will be able to access the items using Items.A and Items.B.


You can also selectively choose files using:

import { A, C } from "dir/*";

which in the above example would convert to:

import A from "./dir/a";
import C from "./dir/c";

The above is like doing:

import * as temp from "dir";
const { A, C } = temp;

There is also simple Glob support so given the directory structure:

|- index.js
|- dir
    |- a.js
    |- a.spec.js
    |- b.js
    |- b.spec.js

this import:

import * as tests from './dir/*.spec';

will compile to:

import aSpec from './dir/a.spec';
import bSpec from './dir/b.spec';

Files are automatically camel-cased and in the import statements the extensions are clipped unless specified otherwise (see below)

Information

  • File extensions are removed in the resulting variable. Dotfiles will be imported without their preceding . (e.g. .foo -> Foo or foo depending on settings)
  • in an import { ... } from 'foo/*', the identifiers inside { ... } are the same as what their name would be if you were to import the whole directory. This means it is the files' names' pascal/camel-cased and extensions removed etc. by default (depending on settings of course).

Options

babel-plugin-wildcard allows you to change various settings by providing an options object by using the following instead:

{
    plugins: [
        ['wildcard', { options }]
    ]
}

where { options } is the options object. The following options are available:

exts

By default, the files with the following extensions: ["js", "es6", "es", "jsx"], will be imported. You can change this using:

{
    plugins: [
        ['wildcard', {
            'exts': ["js", "es6", "es", "jsx", "javascript"]
        }]
    ]
}

If you add the extension "", it will also import subdirectories.

nostrip

By default, the file extension will be removed in the generated import statements, you can change this using:

{
    plugins: [
        ['wildcard', {
            'nostrip': true
        }]
    ]
}

This is useful when the extension of your source files is different from the outputted ones. (e.g. .jsx to .js).

useCamelCase

By default the name is converted to PascalCase, if you prefer camelCase, you may set this option to true:

{
    plugins: [
        ['wildcard', {
            'useCamelCase': true
        }]
    ]
}

noModifyCase

By default, the name will be automatically pascal cased, the following regex is used to extract the words, those words then have their first letter capitalized and are joined together:

[A-Z][a-z]+(?![a-z])|[A-Z]+(?![a-z])|([a-zA-Z\d]+(?=-))|[a-zA-Z\d]+(?=_)|[a-z]+(?=[A-Z])|[A-Za-z0-9]+

you can disable this behavior using:

{
    plugins: [
        ['wildcard', {
            'noModifyCase': true
        }]
    ]
}

Extensions are still removed (except dotfiles, see "Information").

babel-plugin-wildcard's People

Contributors

drgould avatar dword-design avatar louislva avatar pamidur avatar puck7744 avatar simding avatar test123456789012345 avatar vihanb 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

babel-plugin-wildcard's Issues

Import { ... } as wildcard

I'm using this plugin in my babel/webpack/React workflow and it's fantastic! One thing I would like to see is the ability to use the specific import syntax with directories because I don't want my imports inside an object.

Currently I do this:

import * as things from 'src/things'
const { ThingA, ThingB, ThingC } = things

And that works well enough, but I would like to be able to do this:

import { ThingA, ThingB, ThinbC } from 'src/things'

Thanks for writing this wonderful little plugin!

Additional features

Hello!
Very nice plugin!
Can you add more functionality to it?

  1. Possibility to import nested folder's index.js by folder name.
    I have such a project structure
/components
   /Button
      index.js
      style.css
   /Header
      index.js
      style.css

Is it possible to import components like this?

import { Button, Header } from './components/*'
  1. Possibility to import nested folder's directory named file by folder name like Webpack DirectoryNamedWebpackPlugin does
    There is an implementation of it for Babel, but it is not supported any more. mdluo/babel-plugin-directory-named-module#1

It would be great to get rid of index.js all over my React Native project.
Thanks in advance for your help!

Handle Proper Recursive Imports with `index.js`

PR #11 introduced Recursive Imports, but do not properly require index.js with special behavior. Ideally when a directory with both index.js and sibling files is imported, the index.js file is set to the base alias and is then extend with properties that match the sibling file names.

For example:

|- index.js
|- dir
    |- a.js
    |- c.js
    |- nested
        |- index.js
        |- b.js

The following should be possible:

import * as Items from './dir';

console.log(Items.Nested()); // Whatever is in './nested/index.js'
console.log(Items.Nested.B()); // Whatever is in './nested/b.js'

Not working

Hello, I cant get it to work Am I doing something wrong?

Source

import db from 'Server/data/sequelize'
import * as mahalo from './*'

delete models.Index

Output

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _sequelize = _interopRequireDefault(require("../sequelize"));

var _index = _interopRequireDefault(require("./index.js"));

var _UserSession = _interopRequireDefault(require("./UserSession.js"));

var _UserProfile = _interopRequireDefault(require("./UserProfile.js"));

var _UserLogin = _interopRequireDefault(require("./UserLogin.js"));

var _User = _interopRequireDefault(require("./User.js"));

var _Post = _interopRequireDefault(require("./Post.js"));

var _ItemImage = _interopRequireDefault(require("./ItemImage.js"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

delete models.Index;

.babelrc

{
  "plugins": [
    "transform-es2015-modules-commonjs",
    ["module-resolver", {
      "alias": {
        "Server": "./src/server",
        "Ducks": "./src/ducks",
        "Lib": "./src/lib",
        "Core": "./src/server/core"
      }
    }],
    "wildcard"
  ],
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": { "node": "6" },
        "modules": false,
        "useBuiltIns": false,
        "debug": false
      }
    ],
    "@babel/preset-stage-2",
    "@babel/preset-react",
    "@babel/preset-flow"
  ]
}

babel 7

noModifyCase not working

My config:

{
  "presets": ["env"],
  "plugins": [
    "jsx-event-modifiers",
    "transform-vue-jsx",
    ["wildcard", {
      'noModifyCase': true,
      "exts": ["js", "es6", "es", "jsx", "javascript", "vue"]
    }]
  ]
}

I have a filename sec_1_column.jsx, which still becomes Sec1Column.

Conflict when importing everything from a regular package

First of all, thanks for publishing this! Really helps clean up code ๐Ÿ‘ .

We've started using this in a project we're working on, and when performing wildcard imports of existing modules instead of folders (for example, import * as Animatable from 'react-native-animatable'), the import is understandably broken.

I expected this plugin to understand if we're importing a folder or importing methods from a module, or at least a way to disable the wildcard import behaviour on a per-import basis, am I correct in this expectation? Is there a way I can import * from a module?
Thanks!

Proper Filtering with Recursive Imports

PR #11 introduced recursive imports however does not properly handle filtering at the import level for deep imports.

|- index.js
|- dir
    |- a.js
    |- c.js
    |- nested
        |- d.js
        |- b.js

The following should be possible:

import { A, Nested } from './dir/*';

console.log(A()); // Whatever is in './a.js'
console.log(Nested.D()); // Whatever is in './nested/d.js'
console.log(Nested.B()); // Whatever is in './nested/b.js'

Adding it to plugins breaks my entire app.

I have a very barebones app for doing a simple code example, and adding this makes all of my imports return undefined;

package.json:

"dependencies": {
    "@babel/preset-env": "^7.9.6",
    "babel-plugin-wildcard": "^6.0.0",
    "jest": "^26.0.1"
  }

.babelrc:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "esmodules": true
        }
      }
    ]
  ],
  "plugins": [
    "wildcard"
  ]
}

Add support to syntax `import {path}`

Currently, the following fails:

import "../widgets/actions";

while the following works

import * as Classes from "../widgets/actions";

In my case, just loading the files has the side-effect I want. I would like to avoid having an unused var.

wildcard and resolve.alias can't work at the same time

wildcard and resolve.alias can't work at the same time
my project is built with VueCli3
webpack set the resolve.alias '@'
folder:

src/
โ”œโ”€ views/
โ”‚   โ”œโ”€ index.vue
โ”‚   โ”œโ”€ test.vue

code:

import { Index as temp } from '@/views/*';
console.log(temp);

error:Uncaught Error: Cannot find module '@/views/*'

Does not work with React Native

When attempting to use with React Native, I run into an error when attempting to import a bunch of JSON files. Even though the variable is very clearly defined, when I attempt to interact with it it fails gloriously ๐Ÿ˜„. It does not appear to be the actual import causing issues, but rather the interactions with it. Any ideas?

// NOTE: '@ts-ignore' is required to avoid TypeScript "invalid path" issues
// @ts-ignore
import * as overrides from '../overrides/*.json';
 ERROR  ReferenceError: Can't find variable: overrides
 ERROR  Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect.
      This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
 ERROR  Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect.
      This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.

babel.config.js

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    ['wildcard', { exts: ['json'] }],
    [ 'module-resolver', { alias: { ... } } ],
  ],
};

Can add support for lazy loading?

Hi there,
wonder if there is config parameter to control lazy loading.
For example (from doc) instead of:

const Items = {};
import _wcImport from "./dir/a";
Items.A = _wcImport;

desired result when lazy:

const Items = {};
Object.defineProprty(Items, 'A', {
  get: () => require('./dir/a')
});

Wrong plugin name in README

In several places you use 'include' as plugin name.

{
    plugins: [
        ['include', {
            'nostrip': true
        }]
    ]
}

Should it be like this?

Also can you use double quotes in examples as it is standard for json syntax and .babelrc is a json?

{
    "plugins": [
        ["wildcart", {
            "nostrip": true
        }]
    ]
}

Can't make it work on React

Hi there. I had no problem running this plugin with React Native, but with react i always get
Module not found: Can't resolve './myFolder'

Here is my .babelrc

{
  "plugins": ["wildcard"],
  "presets": ["react"]
}

and my package.json

  "dependencies": {
    "babel-plugin-wildcard": "^5.0.0",
    "react": "^16.4.2",
    "react-dom": "^16.4.2",
    "react-router-dom": "^4.3.1",
    "react-scripts": "1.1.4"
  },
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1"
  }

Thanks.

Support for json

Hi!
You have a great package! Thanks!

Can you add support for .json files? We need it to load all available translations at once from this filestructure

translations/
   en.json
   de.json
   ...

It does not work for me with WebPack

This looks really great. When I try to use it the following works:

import './views/*';

But this does not:

import * as Components from './components/*';

When I look in the browser to what is compiled to, I see:

/* harmony import */ var _views_Workers_vue__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./views/Workers.vue */ "./src/views/Workers.vue");
/* harmony import */ var _views_Results_vue__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./views/Results.vue */ "./src/views/Results.vue");
/* harmony import */ var _views_Jobs_vue__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./views/Jobs.vue */ "./src/views/Jobs.vue");
/* harmony import */ var _components_TestComponent_vue__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./components/TestComponent.vue */ "./src/components/TestComponent.vue");

So for some reason the code which would create Components object is missing. Otherwise it correctly detects all files.

I am using this with a project made with vue-cli where it uses WebPack and Babel.

using it in jspm setup?

Have you tried it on jspm setup? For me it doesn't work, as I got:

Uncaught (in promise) Error: (SystemJS) Unknown plugin "babel-plugin-wildcard"

My config.js looks like this:

System.config({
...
babelOptions: {
    "optional": [
      "runtime",
      "optimisation.modules.system"
    ],
    "plugins": [
      "babel-plugin-wildcard"
    ]
  },
map: {
    "babel": "npm:[email protected]",
    "babel-plugin-wildcard": "npm:[email protected]",
...

Eslint import resolver support

Apologies if this issue has already been raised, I couldn't find a mention of it in this repo.

I'm running into issues using this library along with eslint-plugin-import. Statements like:

import { MyComponent } from '../components/*' 

throw the rule: Unable to resolve path to module '../components/*'.

However, the code still compiles and runs with webpack.

Are there any plans to create a resolver to handle these cases, like this one for babel-plugin-module-resolver? Or is there some configuration that will solve this that I've missed?

An option to exclude some files

Could we somehow exclude particular files from being imported? I mean especially the situation when the index file is in the same folder as the ones we would like to import. Right now we have to create a separate folder to isolate them.

Regex import

Is it possible to use some regex way to import only specific files (and ignoring the ones that would not match the regex)?

Babel 7 support

Is this planned? The devDeps in the package.json are referencing 6 atm

Proper File Globbing with Recursive Imports

PR #10 introduced File Globbing, and shortly afterwards PR #11 introduced Recursive Imports. However the two features do not mesh properly together.

For example:

|- index.js
|- dir
    |- before_a.js
    |- c.js
    |- before_nested
        |- b.js

The following should be possible:

import * as Before from './dir/before_*';

console.log(Before.BeforeA()); // Whatever is in './before_a.js'
console.log(Before.BeforeNested.B()); // Whatever is in './before_nested/b.js'

@drgould does the above look right to you?

cacheDirectory is breaking functionality

Hey there, great plugin, however I'm having some issues using this with my webpack framework. When using babel-loader with the cacheDirectory option and deleting some files within that directory, I get module not found errors. Deleting my babel-loader cache (node_modules/.cache/babel-loader) or setting cacheDirectory to false fixes this problem.

Can't import multiple files with same names that have different extensions

if I have three files:

|- dir
  |- A.json
  |- A.atlas
  |- A.png

then I do this:

import * as Items from './dir';
console.log(Items)

It will only show:

A:.../dir/A.atlas

It can't import all three files.
So I think maybe we can add an option to let the variables include their extensions.
Something like this:

A_json:.../dir/A.json
A_atlas:.../dir/A.atlas
A_png:.../dir/A.png

I know there's a way to do this in index.js:

if(_path3.default.extname(file) !== '') {
  fancyName = fancyName + '_' + _path3.default.extname(file).substring(1);
}

But I would appreciate it if I could choose to switch it.

Ability to filter files

I'm trying to import a list of images dynamically in react-native.
Somes images have higher resolutions, so I would have img1.png, [email protected] etc..
I only want to import files in a folder that do not have the "@" character in their name.
Would it be possible to have an exclusion/filter option?

Thanks!

Pascal Case is used for file names

You are currently using Pascal Case as default for file names, not Camel Case. Can you change this?

With Camel Case file name like this my-test-file.js should be myTestFile, but get MyTestFile.

You can use humps library for file names conversion https://www.npmjs.com/package/humps

Also you can update api with something like this if you want

{
    "plugins": [
        ["wildcard", {
           "camelizeNames": true
        }]
    ]
}

{
    "plugins": [
        ["wildcard", {
           "pascalizeNames": true
        }]
    ]
}

Cannot use wildcards in Vue Single-File-Components files

Importing a full directory of files only seems to work when the statement is used in a *.js file.
I can at least import other file types (like *.vue files) but unfortunately I'm trying to get the initial import statement to work in a root app.vue file, instead of falling back on importing a separate *.js file that serves as an "includes" file for the directories I need to import.

Example, a folder structure containing:

  • app.vue
    ./ui/
    - button.vue
    - checkbox.vue
    ./views/
    - projects.vue
    - demos.vue

In app.vue:

import * as ui from './ui/*';
import * as views from './views/*';

export default {
        components: _.extend( {}, ui, views ),
 ...
}

I get this error:

Error: Can't resolve './ui/*' in 'D:\path-of-my-project\vue'

Unable to get this working with Vue SFC (Single File Components, *.vue files)

I placed this in my Webpack configuration (and I also have the .babelrc config file containing the "plugins": ["wildcard"] setting, but still no dice.

{
	entry: {
		'bundle': '......./js/entry.js',
	},

	output: {
		path: path.resolve($$$.paths.dist),
		filename: "[name].js"
	},

	module: {
		rules: [
			{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
			{ test: /\.vue$/, use: [ 'vue-loader' ] },
			{ test: /\.js$/, use: {
				loader: 'babel-loader',
				options: {
					babelrc: true,
					presets: ['@babel/preset-env'],
				}
			}},
		]
	}
}

Then in my entry.js file, I'm trying to populate a "pages" variable with all the *.vue files with this, but it fails (results an empty object):

import * as pages from '../vue/page-*';

Do I have to add some file-extensions to the config or something?

Sub dirs

Is it working with sub directories? Something like that?

  • FunsToImport
    --somefile.js
    --subdir1
    ---somefile2.js

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.