Code Monkey home page Code Monkey logo

aliasify's Introduction

Build Status Coverage Status

Aliasify is a transform for browserify which lets you rewrite calls to require.

Installation

Install with npm install --save-dev aliasify.

Usage

To use, add a section to your package.json:

{
    "aliasify": {
        "aliases": {
            "d3": "./shims/d3.js",
            "underscore": "lodash"
        }
    }
}

Now if you have a file in src/browserify/index.js which looks like:

d3 = require('d3')
_ = require('underscore')
...

This will automatically be transformed to:

d3 = require('../../shims/d3.js')
_ = require('lodash')
...

Any replacement that starts with a "." will be resolved as a relative path (as "d3" above.) Replacements that start with any other character will be replaced verbatim (as with "underscore" above.)

Configuration

Configuration can be loaded in multiple ways; You can put your configuration directly in package.json, as in the example above, or you can use an external json or js file. In your package.json:

{
    "aliasify": "./aliasifyConfig.js"
}

Then in aliasifyConfig.js:

module.exports = {
    aliases: {
        "d3": "./shims/d3.js"
    },
    verbose: false
};

Note that using a js file means you can change your configuration based on environment variables.

Alternatively, if you're using the Browserify API, you can configure your aliasify programatically:

aliasifyConfig = {
    aliases: {
        "d3": "./shims/d3.js"
    },
    verbose: false
}

var b = browserify();
b.transform(aliasify, aliasifyConfig);

note that using the browserify API, './shims/d3.js' will be resolved against the current working directory.

Configuration options:

  • aliases - An object mapping aliases to their replacements.
  • replacements - An object mapping RegExp strings with RegExp replacements, or a function that will return a replacement.
  • verbose - If true, then aliasify will print modifications it is making to stdout.
  • configDir - An absolute path to resolve relative paths against. If you're using package.json, this will automatically be filled in for you with the directory containing package.json. If you're using a .js file for configuration, set this to __dirname.
  • appliesTo - Controls which files will be transformed. By default, only JS type files will be transformed ('.js', '.coffee', etc...). See browserify-transform-tools documentation for details.

Relative Requires

When you specify:

aliases: {
    "d3": "./shims/d3.js"
}

The "./" means this will be resolved relative to the current working directory (or relative to the configuration file which contains the line, in the case where configuration is loaded from package.json.) Sometimes it is desirable to literally replace an alias; to resolve the alias relative to the file which is doing the require call. In this case you can do:

aliases: {
    "d3": {"relative": "./shims/d3.js"}
}

This will cause all occurences of require("d3") to be replaced with require("./shims/d3.js"), regardless of where those files are in the directory tree.

Regular Expression Aliasing

You can use the replacements configuration section to create more powerful aliasing. This is useful if you have a large project but don't want to manually add an alias for every single file. It is also incredibly useful when you want to combine aliasify with other transforms, such as hbsfy, reactify, or coffeeify.

replacements: {
    "_components/(\\w+)": "src/react/components/$1/index.jsx"
}

Will let you replace require('_components/SomeCoolReactComponent') with require('src/react/components/SomeCoolReactComponent/index.jsx')

You can also match an alias and pass a function which can return a new file name.

require("_coffee/delicious-coffee");

Using this configuration:

replacements: {
    "_coffee/(\\w+)": function (alias, regexMatch, regexObject) {
        console.log(alias); // _coffee/delicious-coffee
        console.log(regexMatch); // _coffee/(\\w+)
        return 'coffee.js'; // default behavior - won't replace
    }
}

Stubbing Out Packages

You can remove a package entirely for browser builds using:

aliases: {
    "d3": false
}

Now any code which tries to require('d3') will end up compiling to:

var d3 = {};

Support aliasing requireish function calls

You can tell aliasify to also replace aliases in other functions than require. This can become very helpful if you are planing on wrap node's require function with another one. For example in case of proxyquireify this is very helpful.

    var aliasify = require("aliasify").requireish(["require", "foo", "bar"])

with this options:

aliases: {
        "d3": {"relative": "./shims/d3.js"}
    }

Now any code which tries to require('d3') or foo('d3') or even bar('d3') will end up compiling to:

require("./shims/d3.js") respectively foo("./shims/d3.js") respectively bar("./shims/d3.js")

The argument for requireish() can be either a string or an array of strings.

A few things to note: first, if you specify requireish, you must explicitly list require in the list of requireish things to transform, or it won't be.

Second, note that aliasify only replaces the first string parameter of the "requireish" function call. All other arguments are preserved as they were passed in. (e.g. require('d3', 'foo') turns into require('./shims/d3.js', 'foo').) Caution! Do NOT pass in arguments that have circular references. If you need that, than just pass in an identifier for the object having circular references!

Alternatives

aliasify is essentially a fancy version of the browser field from package.json, which is interpreted by browserify.

Using the browser field is probably going to be faster, as it doesn't involve running a transform on each of your files. On the other hand, aliasify gives you a finer degree of control and can be run before other transforms (for example, you can run aliasify before debowerify, which will let you replace certain components that debowerify would otherwise replace.)

aliasify's People

Contributors

cape-dev avatar eventualbuddha avatar jeanlauliac avatar jmm avatar justinhoward avatar jwalton avatar linuxbasic avatar martinheidegger avatar mkuklis avatar rockuw avatar roncli avatar stuff avatar zaim 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

aliasify's Issues

how to ignore the non-css file

error info:

events.js:141
      throw er; // Unhandled 'error' event
      ^

TypeError: Cannot read property './main/style/basic.css' of undefined (while aliasify was processing /home/develop/Projects/project/js/main.js) while parsing file: /home/develop/Projects/project/js/main.js (while aliasify was processing /home/develop/Projects/project/js/main.js) while parsing file: /home/develop/Projects/project/js/main.js
    at getReplacement (/home/develop/Projects/project/node_modules/aliasify/lib/aliasify.js:21:16)
    at /home/develop/Projects/project/node_modules/aliasify/lib/aliasify.js:48:21
    at /home/develop/Projects/project/node_modules/browserify-transform-tools/lib/transformTools.js:235:16
    at /home/develop/Projects/project/node_modules/browserify-transform-tools/lib/transformTools.js:176:18
    at walk (/home/develop/Projects/project/node_modules/browserify-transform-tools/node_modules/falafel/index.js:58:9)
    at /home/develop/Projects/project/node_modules/browserify-transform-tools/node_modules/falafel/index.js:55:17
    at Array.forEach (native)
    at forEach (/home/develop/Projects/project/node_modules/browserify-transform-tools/node_modules/falafel/index.js:9:31)
    at walk (/home/develop/Projects/project/node_modules/browserify-transform-tools/node_modules/falafel/index.js:43:9)
    at /home/develop/Projects/project/node_modules/browserify-transform-tools/node_modules/falafel/index.js:50:25

aliasify:

// see https://github.com/benbria/aliasify#configuration
mudule.exports = {
    replacements: {
    },
    appliesTo: {
        includeExtensions: ['.js'],
        excludeExtensions: ['.css']
    },
    verbose: true
};

Replace sub-module's relative require

.transform("aliasify", { global:true, aliases:{ "whatwg-url/lib/utf8": "utf8-typed" }})

I've even tried using the full path as the key:

.transform("aliasify", { global:true, aliases:{ [require.resolve("whatwg-url/lib/utf8")] : "utf8-typed" }})

The file that I'm trying to alias is, by default, required internally with require("./utf8").

Instead, the above aliases function as if being ignored.

working with folders ?

I would like to know if there is any way to handle folder, something like this :

{
    "aliasify": {
        "aliases": {
            "directives": "./directives/"
        }
    }
}

Now, anywhere in my js files:

var customDirective = require('directives/cutom-dir')

Thanks !

No value is exported from my es6 module after applying aliasify transform

I have an underscore-extend file that I'd like to alias for all calls to require('underscore'). The reason for this is I'm mixing in some of my own functions to underscore and I'd like them to be available anywhere underscore is required in my codebase.

Here's my underscore-extend.js:

import _ from 'vendor/underscore'

_.mixin({
...
})

export default _

And my gulp task code:

 let b = browserify({
    entries: `./app/${app}/index.js`, 
    debug: true,
    detectGlobal: false,
    paths: [
      './app/shared/',
      './app/shared/lib/',
      './app/'
    ]
  }).transform(browserifyShim) // config must be in package.json
    .transform('babelify', {presets: ['es2015'], compact: false})
    .transform('brfs')
    .transform(aliasify, {
      aliases: {
        vendor: './vendor',
        underscore: {relative: 'shared/lib/underscore-extend'}
      },
      verbose: false,
      debug: true
    })

The problem is that there is no value exported from underscore-extend when I use import _ from 'underscore'. When I used import 'underscore', _ is defined correctly in scope and all my mixins are present, but I'd rather not change my entire codebase to use import without assignment.

I've also tried underscore: './app/shared/lib/underscore-extend' and got the same result.

regex in aliases

Any plan to support regex in aliases config? I'm happy to contribute too

Replace alias in dependencies?

I've been doing some testing on using aliasify to replace requires of underscore for lodash. I've enabled verbose to be true. I've ran into an issue where in Backbone it still requires underscore instead of lodash.

See the output below:

Output:

aliasify - /Users/michaelbenin/Projects/node-startup/apps/about/about_view.js: replacing underscore with lodash
aliasify - /Users/michaelbenin/Projects/node-startup/apps/home/home_view.js: replacing underscore with lodash
aliasify - /Users/michaelbenin/Projects/node-startup/apps/links/links_view.js: replacing underscore with lodash
aliasify - /Users/michaelbenin/Projects/node-startup/apps/login/login_view.js: replacing underscore with lodash
aliasify - /Users/michaelbenin/Projects/node-startup/apps/search/search_view.js: replacing underscore with lodash
aliasify - /Users/michaelbenin/Projects/node-startup/apps/searchquery/searchquery_view.js: replacing underscore with lodash
aliasify - /Users/michaelbenin/Projects/node-startup/apps/signup/signup_view.js: replacing underscore with lodash
aliasify - /Users/michaelbenin/Projects/node-startup/apps/topics/topics_view.js: replacing underscore with lodash
aliasify - /Users/michaelbenin/Projects/node-startup/apps/users/users_view.js: replacing underscore with lodash
aliasify - /Users/michaelbenin/Projects/node-startup/apps/home/home_sub_view.js: replacing underscore with lodash
aliasify - /Users/michaelbenin/Projects/node-startup/apps/nav/nav_view.js: replacing underscore with lodash
aliasify - /Users/michaelbenin/Projects/node-startup/apps/footer/footer_view.js: replacing underscore with lodash
>> Error: Cannot find module 'underscore' from '/Users/michaelbenin/Projects/node-startup/node_modules/backbone'

Configuration:

var aliasify = require('aliasify');

var aliasifyConfig = {
  aliases: {
    underscore: 'lodash'
  },
  verbose: true
};

// in my browserify file:

b.transform(aliasify, aliasifyConfig);

Support for wildcards

Browserify's official way to support local modules is to put them in the node_modules folder and add an exception in the .gitignore

A way to do wildcard aliases would be great:

'app/*' : './local_modules/*'

Cannot manage to alias react/addons to react

I am experementing a bit with react, browserify and aliasify and I have these wishes:

  • I want to bundle all code written by me into a single file
  • I want to bundle all 3rd party dependencies (react, react-router, lodash etc) into separate files, one for each lib, to maximize caching possibilities

I have managed to do the things described above but I ran into this specific situation:

In some places of my code I want to use react with addons and as such require it like this: var React = require('react/addons). I don't do this in all parts of my code and it is not done in 3rd party dependencies such as react-router.

I tried to solve this situation with aliasify like this for all my extrnal modules

var b = browserify()
var aliasTransform = aliasify.configure({
  aliases: {
    react: 'react/addons'
  }
})
b.transform(aliasTransform)
b.external('react') // have also tried 'react/addons'
b.require('react-router')
b.bundle()

What happens when I load my page is that I get the error Cannot find module 'react' originating from the react-router module.

Should it be possible to do what I am trying to do?

More general question on stackoverflow

Is there support for bower installations with aliasify?

When using the following configuration:

exports.aliasConfig = {
  aliases: {
    'modernizr': {
      'relative': '<bower_directory>/modernizr/modernizr.js'
    },
    'lodash': {
      'relative': '<node_modules_directory>/lodash/index.js'
    }
  },
  configDir: 'dist',
  verbose: true
}

(Obviously omitting the directories above with placeholders). The node_modules/* aliases work fine, but the bower aliases do not. I'm using the CommonJS requires for bower in my source code i.e require('modernizr);`.

If there's no support, would you be open to a pull request to fix it?

Aliasify code in modules

I have an project that requires a library which uses the request library. For it to work in the browser i have to swap that for the browser-request.
Is there a way for aliasify to update requires in dependencies?

support for alias value of false like the browser field, maps to empty module

It would be nice if aliasify would also support simply setting an alias value to false indicating that an empty module would need to be used as the replacement.

{
    "aliasify": {
        "aliases": {
            "crypto": false
        }
    }
}

This would cause crypto to be replaced with a require to an empty module just like browserify handles the false for its browser field.

Without this change, one needs to specify this:

{
    "aliasify": {
        "aliases": {
            "crypto": "browserify/lib/_empty"
        }
    }
}

With this change, it is more intuitive to the user since it works like browser field and we aren't exposing a path browserify's empty which is private. We can keep the path internal to aliasify and adjust as necessary or even just include our own empty file which we point to (maybe that is even better).

It is a pretty common need to stub out requires for the browser so making this easy is a big win.

I would have submitted a PR since this probably just an extra if statement, but my coffeescript skills are pretty lacking.

Thanks for a great module!

Issues when using npm shrinkwrap or npm ls because of node-falafel

Hi there

There is a long running issue with node-falafel that uses esprima as a bundledDependencies https://github.com/substack/node-falafel/blob/master/package.json#L25 and therefore causing "ERR! extraneous: [email protected]".

There are several issues already open and even pull requests:
https://github.com/substack/node-falafel/issues/30
https://github.com/substack/node-falafel/issues/28
https://github.com/substack/node-falafel/pull/29

I don't understand why this doesn't get fixed. I respect substack and understand he has a lot on his plate but this issue is going on for too long and it'd just be a matter of accepting a PR.

As a workaround I could see the following options:

  • Someone creates a fork of node-falafel, fixes the issue and publish to npm so we can all switch our libraries to use the new dependency
  • Someone close to substack physically forces him to accept the pull request https://github.com/substack/node-falafel/pull/29 ๐Ÿ˜„
  • If you don't mind switching to node-burrito this is probably also an alternative

What do you think?

Cheers
Gion

Allowing paths after alias causes error when requiring sub-modules

First, my specific example that led to finding this issue:

I have source modules that may require either the core React module or the React module with addons, such as:

var React = require('react');
// OR
var React = require('react/addons');

I am attempting to use aliasify to map any requires of react to react/addons. However, I want to leave requires for react/addons untouched. When I include the following in my package.json, require('react/addons') becomes require('react/addons/addons'):

"aliasify": {
  "aliases": {
    "react": "react/addons"
  }
}

At first, I thought this might be a bug with aliasify being too lenient, but it looks like it's expected functionality, considering this test to ensure paths after aliases are maintained.

I attempted to work around this by using quote marks in my package.json, like so:

"aliasify": {
  "aliases": {
    "'react'": "'react/addons'"
  }
}

Hoping that I would be able to do an 'exact' match against only requires for 'react', but to no avail.

This pattern of modules exposing differing or extended functionality via sub-modules (e.g. Less 2.0.0 just introduced less/browser as a valid require target) seems to not be that uncommon, so I was curious as to whether you feel there's a way to improve aliasify to be smarter about aliasing modules names with this pattern.

Thanks.

Not working with Vue?

Hi there,

I'm using aliasify to make vue work in browserify - however it doesn't seem to reply the require.

My package.json

{
  "private": true,
  "scripts": {
    "prod": "gulp --production",
    "dev": "gulp watch"
  },
  "devDependencies": {
    "aliasify": "^2.0.0",
    "bootstrap-sass": "^3.3.7",
    "gulp": "^3.9.1",
    "jquery": "^3.1.0",
    "laravel-elixir": "^6.0.0-9",
    "laravel-elixir-browserify-official": "^0.1.3",
    "laravel-elixir-vue-2": "^0.2.0",
    "laravel-elixir-webpack-official": "^1.0.2",
    "lodash": "^4.16.2",
    "vue": "^2.0.1",
    "vue-resource": "^1.0.3"
  },
  "aliasify": {
    "aliases": {
      "vue": "vue/dist/vue.js",
      "underscore": "lodash"
    }
  } 
}

And my bootstrap.js


window._ = require('lodash');

/**
 * We'll load jQuery and the Bootstrap jQuery plugin which provides support
 * for JavaScript based Bootstrap features such as modals and tabs. This
 * code may be modified to fit the specific needs of your application.
 */

window.$ = window.jQuery = require('jquery');
require('bootstrap-sass');

/**
 * Vue is a modern JavaScript library for building interactive web interfaces
 * using reactive data binding and reusable components. Vue's API is clean
 * and simple, leaving you to focus on building your next great project.
 */

window.Vue = require('vue');
require('vue-resource');

/**
 * We'll register a HTTP interceptor to attach the "CSRF" header to each of
 * the outgoing requests issued by this application. The CSRF middleware
 * included with Laravel will automatically verify the header's value.
 */

Vue.http.interceptors.push((request, next) => {
    request.headers.set('X-CSRF-TOKEN', Laravel.csrfToken);

    next();
});

/**
 * Echo exposes an expressive API for subscribing to channels and listening
 * for events that are broadcast by Laravel. Echo and event broadcasting
 * allows your team to easily build robust real-time web applications.
 */

// import Echo from "laravel-echo"

// window.Echo = new Echo({
//     broadcaster: 'pusher',
//     key: 'your-pusher-key'
// });

What am I doing wrong?

Directory separator should be / always

Currently it use "" directory separator on Windows. It ends in:
"..\node_modules\browserify\node_modules\browser-pack_prelude.js"
instead of:
"../node_modules/browserify/node_modules/browser-pack/_prelude.js".

It happens due using path.relative(root, file); in mapPathRelativeTo.

Does aliasify work with CoffeeScript files?

I am using grunt-browserify with these transforms declared in my package.json:

"browserify": {
  "transform": [
    "aliasify",
    "coffeeify",
    "browserify-shim"
  ]
}

When aliasify scans my CoffeeScript files then I get an error because it does not like CoffeScript symbols like ?=:

SyntaxError: Unexpected token (1:10) (while aliasify was processing config.coffee)

What can I do to make aliasify work with CoffeeScript?

I want to replace statements like:

CoreEvent = require '../../../core/coffee/event/CoreEvent.coffee'

Alias and dot notation

Hello!

Is it possible to do something like this:

var cat = require("animals").cat;

->

var cat = require("../shim/to/animals.js").dog;

?

Thanks!

Does not work if code contains ES6 syntax

The aliasify transform will fail if code contains ES6 syntax. So far, both usage of const and template strings cause issues. I will follow up with exact error message.

Support .jsx files

Currently only .js and .coffee files are supported via this option.

jsFilesOnly: true

A lot of people are now using React with .jsx . jsFilesOnly option needs to change to a list of file extensions. I would submit to browserify-transform-tools, but that repo hasn't been maintained in almost a year.

Always resolve relative urls relative to package.json

note that using the browserify API, './shims/d3.js' will be resolved against the current working directory.

and separately:

configDir - An absolute path to resolve relative paths against. If you're using package.json, this will automatically be filled in for you with the directory containing package.json. If you're using a .js file for configuration, set this to __dirname.

In my opinion it would make sense to always resolve against package.json (except of course when file-relative operation is enabled through {relative: "replacement"}). Especially it would allow one to use aliasify for package-relative paths in package.json like this:

{
  "name": "mypkg",
  "browserify": {
    "transform": [
      [
        "aliasify",
        {
          "aliases": {
            "jquery": "./jquery.custom"
          } 
        }
      ]
    ]
  }
}

.. where jquery.custom is in the same directory as the package.json file. Then it would still "just work" even when somebody else depends on mypkg.

I understand that you might not want to break backwards compatibility with existing implementations that have implemented paths based on how they work now; it would require a major release. But perhaps you could introduce a config option to enable the new behaviour until then?

        {
          "aliases": {
            "jquery": "./jquery.custom"
          },
          "usePackageRelativePaths": true
        }

There are plenty of npm packages available to figure out the associated package.json file location. For example this looks decent: https://www.npmjs.com/package/pkg-up

npm publish

Hello @benbria

I would like to use aliasify but did not found it in the npm repository. Could you publish it?

PS: I would prefer just passing a plain js hash to the transform as I it makes independent from how you handle your configuration:

var builder = browserify();

builder.transform(require('./aliasify')(app.settings.aliasify));

//...

Best,
Bo

Support passing falafel option (for ecmaVersion 6)

There is no way to pass falafel options. It would be nice if there is a way to do this.

I tried to add {falafelOptions: {ecmaVersion:6}} when calling makeRequireTransform, but somehow it doesn't work. The second time falafel is called, falafelOptions disappears. It may be a bug of browserify-transform-tools.

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.