All Projects → asapach → babel-plugin-rewire-exports

asapach / babel-plugin-rewire-exports

Licence: MIT license
Babel plugin for stubbing [ES6, ES2015] module exports

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to babel-plugin-rewire-exports

angular-gulp-starter
Simple dev/prod build for Angular (2+) using gulp, systemjs, rollup, ngc (AOT), scss, Visual Studio
Stars: ✭ 18 (-70.97%)
Mutual labels:  rollup, systemjs
npm-es-modules
Breakdown of 7 different ways to use ES modules with npm today.
Stars: ✭ 67 (+8.06%)
Mutual labels:  rollup, esm
mock-spy-module-import
JavaScript import/require module testing do's and don'ts with Jest
Stars: ✭ 40 (-35.48%)
Mutual labels:  stub, esm
Cuckoo
Boilerplate-free mocking framework for Swift!
Stars: ✭ 1,344 (+2067.74%)
Mutual labels:  unit-testing, stub
InstantMock
Create mocks easily in Swift
Stars: ✭ 88 (+41.94%)
Mutual labels:  unit-testing, stub
Babel Plugin Prismjs
A babel plugin to use PrismJS with standard bundlers.
Stars: ✭ 114 (+83.87%)
Mutual labels:  babel-plugin, rollup
motion-hooks
A simple Hooks wrapper over Motion One, An animation library, built on the Web Animations API for the smallest filesize and the fastest performance.
Stars: ✭ 93 (+50%)
Mutual labels:  rollup, esm
oletus
Minimal ECMAScript Module test runner
Stars: ✭ 43 (-30.65%)
Mutual labels:  unit-testing, esm
Sinon
Test spies, stubs and mocks for JavaScript.
Stars: ✭ 8,828 (+14138.71%)
Mutual labels:  unit-testing, stub
vitext
The Next.js like React framework for better User & Developer experience!
Stars: ✭ 376 (+506.45%)
Mutual labels:  rollup, esm
rollup-plugin-closure-compiler-js
Rollup plugin for optimizing JavaScript with google-closure-compiler-js.
Stars: ✭ 31 (-50%)
Mutual labels:  rollup
helloworld
Boilerplate code for basic architecture of an android application following MVVM pattern using hilt, RxJava2.
Stars: ✭ 26 (-58.06%)
Mutual labels:  unit-testing
rollup-plugin-inject-process-env
Inject environment variables in process.env with Rollup
Stars: ✭ 48 (-22.58%)
Mutual labels:  rollup
apex-rollup
Fast, configurable, elastically scaling custom rollup solution. Apex Invocable action, one-liner Apex trigger/CMDT-driven logic, and scheduled Apex-ready.
Stars: ✭ 133 (+114.52%)
Mutual labels:  rollup
the-art-of-unit-testing
Repository that contains code in Node.js from the book The Art of Unit Testing, Second Edition by Roy Osherove
Stars: ✭ 22 (-64.52%)
Mutual labels:  unit-testing
morq
BDD/TDD assertion interface
Stars: ✭ 80 (+29.03%)
Mutual labels:  unit-testing
pythonista-chromeless
Serverless selenium which dynamically execute any given code.
Stars: ✭ 31 (-50%)
Mutual labels:  unit-testing
11r
America's favorite Eleventy blog template.
Stars: ✭ 135 (+117.74%)
Mutual labels:  rollup
Restaurants
Restaurants sample app built with the new architecture components (LiveData, Room, ViewModel) and Dagger 2
Stars: ✭ 47 (-24.19%)
Mutual labels:  unit-testing
rollup-plugin-generate-package-json
Generate package.json file with packages from your bundle using Rollup
Stars: ✭ 29 (-53.23%)
Mutual labels:  rollup

babel-plugin-rewire-exports

NPM Version NPM Downloads Build Status

Babel plugin for stubbing (ES6, ES2015) module exports. It allows to rewire the exported values in all the importing modules. Unlike babel-plugin-rewire it doesn't modify the module internals (e.g. imports and top-level variables and functions). See How it works section for implementation details.

Exports

Plugin transforms module exports in such a way that they can be stubbed (or "rewired") via the following API:

  • default export - plugin exports additional rewire(stub) function that allows to replace the original
  • named exports - for each export (e.g. export var foo) an additional function rewire$foo(stub) is exported
  • restore() function allows to restore the exports to their original values
  • if there are existing rewire or restore top-level identifiers, the generated exports will be named rewire$default and restore$rewire respectively

Example

Named export:

//------ text.js ------
export let message = 'Hello world!'

//------ logger.js ------
import {message} from './text.js'

export default function () {
  console.log(message)
}

//------ main.js ------
import {rewire$message, restore} from './text.js'
import logger from './logger.js'

logger() // 'Hello world!'
rewire$message('I am now rewired')
logger() // 'I am now rewired'
restore()
logger() // 'Hello world!'

Default export:

//------ fetch.js ------
export default function (url) {
  // perform some expensive remote call
}

//------ adapter.js ------
import fetch from './fetch.js'

export function fetchItems() {
  return fetch('/items')
}

//------ test.js ------
import {rewire, restore} from './fetch.js'
import {fetchItems} from './adapter.js'

// Jasmine example
describe('adapter', function () {
  beforeEach(function () {
    rewire(this.spy = jasmine.createSpy('fetch'))
  })
  afterAll(restore)
  
  it('should call fetch', function () {
    fetchItems()
    expect(this.spy).toHaveBeenCalledWith('/items')
  })
})

// Mocha/Chai and Sinon example
describe('adapter', function () {
  var spy

  beforeEach(function () {
    rewire(spy = sinon.spy())
  })
  after(restore)
  
  it('should call fetch', function () {
    fetchItems()
    expect(spy.withArgs('/items').calledOnce).to.be.true
  })
})

Compatibility

How it works

In ES6, imports are live read-only views on exported values:

//------ lib.js ------
export let counter = 3;
export function incCounter() {
    counter++;
}

//------ main1.js ------
import { counter, incCounter } from './lib';

// The imported value `counter` is live
console.log(counter); // 3
incCounter();
console.log(counter); // 4

// The imported value can’t be changed
counter++; // TypeError

This allows for any exports to be overwritten from within the module - and imports will be automatically updated via their bindings.

Transformations

Here's how various kinds of export declarations are transformed:

  • Literals (export default 'foo') - the original value is copied to a variable to be stubbed and restored later: export {_default as default}

  • Variables:

    • named exports (export var foo, export let bar or export {baz}) are left intact, but their initial values are similarly copied to temp variables.
    • default export (export default foo) is converted to a named export to enable live binding: export {foo as default}
  • Constants (export const foo = 'bar' or export default foo) are treated similar to variables, but their values are not modified within the module (since they are read-only) - only exported values are rewired:

    • named exports: export { _foo as foo }
    • default export: export { _default as default }

    You can use unsafeConst option to convert const to let in order to enable live binding.

  • Functions (export default function () {…} or export function foo() {…}) are converted into a function expression and exported variable by the same name. The variable initialization is hoisted to the top of the scope to preserve existing behavior.

  • Classes (export default class foo {…} or export class foo {…}) are handled similarly to functions except the variables are not hoisted (again to preserve the existing behavior).

  • Re-exports (export * from './foo.js' or export {bar} from 'baz') are ignored. They can be rewired in the original modules.

  • Immutable values such as undefined, globals and imports are copied similar to literals.

Installation

$ npm install babel-plugin-rewire-exports

Usage

Via .babelrc (Recommended)

.babelrc

// without options
{
  "plugins": ["rewire-exports"]
}

// with options
{
  "plugins": [
    ["rewire-exports", {
      "unsafeConst": true
    }]
  ]
}

Via CLI

$ babel --plugins rewire-exports script.js

Via Node API

require("@babel/core").transform("code", {
  plugins: ["rewire-exports"]
});

Options

unsafeConst

boolean, defaults to false.

Constants cannot be rewired if you're targeting ES2015+, because the plugin relies on variables being assign-able in order to work. However setting unsafeConst: true will convert export const foo = 'bar' to export let foo = 'bar'. This will allow to treat constant exports as regular variables. This is potentially unsafe if your code relies on constants being read-only.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].