Coder Social home page Coder Social logo

expose-loader's Introduction

npm node tests coverage discussion size

expose-loader

The expose-loader loader allows to expose a module (in whole or in part) to global object (self, window and global).

For further hints on compatibility issues, check out Shimming of the official docs.

Getting Started

To begin, you'll need to install expose-loader:

npm install expose-loader --save-dev

or

yarn add -D expose-loader

or

pnpm add -D expose-loader

(If you're using WebPack 4, install expose-loader@1 and follow the corresponding instructions instead.)

Then you can use the expose-loader using two approaches.

Inline

The | or %20 (space) allow to separate the globalName, moduleLocalName and override of expose. The documentation and syntax examples can be read here.

Warning

%20 is space in a query string, because you can't use spaces in URLs

import $ from "expose-loader?exposes=$,jQuery!jquery";
//
// Adds the `jquery` to the global object under the names `$` and `jQuery`
import { concat } from "expose-loader?exposes=_.concat!lodash/concat";
//
// Adds the `lodash/concat` to the global object under the name `_.concat`
import {
  map,
  reduce,
} from "expose-loader?exposes=_.map|map,_.reduce|reduce!underscore";
//
// Adds the `map` and `reduce` method from `underscore` to the global object under the name `_.map` and `_.reduce`

Using Configuration

src/index.js

import $ from "jquery";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: require.resolve("jquery"),
        loader: "expose-loader",
        options: {
          exposes: ["$", "jQuery"],
        },
      },
      {
        test: require.resolve("underscore"),
        loader: "expose-loader",
        options: {
          exposes: [
            "_.map|map",
            {
              globalName: "_.reduce",
              moduleLocalName: "reduce",
            },
            {
              globalName: ["_", "filter"],
              moduleLocalName: "filter",
            },
          ],
        },
      },
    ],
  },
};

The require.resolve call is a Node.js function (unrelated to require.resolve in webpack processing). require.resolve gives you the absolute path to the module ("/.../app/node_modules/jquery/dist/jquery.js"). So the expose only applies to the jquery module. And it's only exposed when used in the bundle.

And run webpack via your preferred method.

Options

Name Type Default Description
exposes {String|Object|Array<String|Object>} undefined List of exposes
globalObject String undefined Object used for global context

exposes

Type:

type exposes =
  | string
  | {
      globalName: string | Array<string>;
      moduleLocalName?: string;
      override?: boolean;
    }
  | Array<
      | string
      | {
          globalName: string | Array<string>;
          moduleLocalName?: string;
          override?: boolean;
        }
    >;

Default: undefined

List of exposes.

string

Allows to use a string to describe an expose.

syntax

The | or %20 (space) allow to separate the globalName, moduleLocalName and override of expose.

String syntax - [[globalName] [moduleLocalName] [override]] or [[globalName]|[moduleLocalName]|[override]], where:

  • globalName - the name in the global object, for example window.$ for a browser environment (required)
  • moduleLocalName - the name of method/variable/etc of the module (the module must export it) (may be omitted)
  • override - allows to override existing value in the global object (may be omitted)

If moduleLocalName is not specified, it exposes the entire module to the global object, otherwise it exposes only the value of moduleLocalName.

src/index.js

import $ from "jquery";
import _ from "underscore";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: require.resolve("jquery"),
        loader: "expose-loader",
        options: {
          // For `underscore` library, it can be `_.map map` or `_.map|map`
          exposes: "$",
          // To access please use `window.$` or `globalThis.$`
        },
      },
      {
        // test: require.resolve("jquery"),
        test: /node_modules[/\\]underscore[/\\]modules[/\\]index-all\.js$/,
        loader: "expose-loader",
        type: "javascript/auto",
        options: {
          // For `underscore` library, it can be `_.map map` or `_.map|map`
          exposes: "_",
          // To access please use `window._` or `globalThis._`
        },
      },
    ],
  },
};

object

Allows to use an object to describe an expose.

globalName

Type:

type globalName = string | Array<string>;

Default: undefined

The name in the global object. (required).

src/index.js

import _ from "underscore";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /node_modules[/\\]underscore[/\\]modules[/\\]index-all\.js$/,
        loader: "expose-loader",
        type: "javascript/auto",
        options: {
          exposes: {
            // Can be `['_', 'filter']`
            globalName: "_.filter",
            moduleLocalName: "filter",
          },
        },
      },
    ],
  },
};
moduleLocalName

Type:

type moduleLocalName = string;

Default: undefined

The name of method/variable/etc of the module (the module must export it). If moduleLocalName is specified, it exposes only the value of moduleLocalName.

src/index.js

import _ from "underscore";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /node_modules[/\\]underscore[/\\]modules[/\\]index-all\.js$/,
        loader: "expose-loader",
        type: "javascript/auto",
        options: {
          exposes: {
            globalName: "_.filter",
            moduleLocalName: "filter",
          },
        },
      },
    ],
  },
};
override

Type:

type override = boolean;

Default: false

By default, loader does not override the existing value in the global object, because it is unsafe. In development mode, we throw an error if the value already present in the global object. But you can configure loader to override the existing value in the global object using this option.

To force override the value that is already present in the global object you can set the override option to the true value.

src/index.js

import $ from "jquery";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: require.resolve("jquery"),
        loader: "expose-loader",
        options: {
          exposes: {
            globalName: "$",
            override: true,
          },
        },
      },
    ],
  },
};

array

src/index.js

import _ from "underscore";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /node_modules[/\\]underscore[/\\]modules[/\\]index-all\.js$/,
        loader: "expose-loader",
        type: "javascript/auto",
        options: {
          exposes: [
            "_.map map",
            {
              globalName: "_.filter",
              moduleLocalName: "filter",
            },
            {
              globalName: ["_", "find"],
              moduleLocalName: "myNameForFind",
            },
          ],
        },
      },
    ],
  },
};

It will expose only map, filter and find (under myNameForFind name) methods to the global object.

In a browser these methods will be available under windows._.map(..args), windows._.filter(...args) and windows._.myNameForFind(...args) methods.

globalObject

type globalObject = string;

Default: undefined

Object used for global context

import _ from "underscore";

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /node_modules[/\\]underscore[/\\]modules[/\\]index-all\.js$/,
        loader: "expose-loader",
        type: "javascript/auto",
        options: {
          exposes: [
            {
              globalName: "_",
            },
          ],
          globalObject: "this",
        },
      },
    ],
  },
};

Examples

Expose a local module

index.js

import { method1 } from "./my-module.js";

my-module.js

function method1() {
  console.log("method1");
}

function method2() {
  console.log("method1");
}

export { method1, method2 };

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /my-module\.js$/,
        loader: "expose-loader",
        options: {
          exposes: "mod",
          // // To access please use `window.mod` or `globalThis.mod`
        },
      },
    ],
  },
};

Contributing

Please take a moment to read our contributing guidelines if you haven't yet done so.

CONTRIBUTING

License

MIT

expose-loader's People

Contributors

alexander-akait avatar anshumanv avatar bard avatar cap-bernardito avatar commanderroot avatar cuongvo avatar dependabot[bot] avatar ersachin3112 avatar evilebottnawi avatar gaearon avatar gdborton avatar harish-sethuraman avatar joshwiens avatar justin808 avatar kevinzwhuang avatar lencioni avatar mabounassif avatar michael-ciniawsky avatar munter avatar shama avatar shellscape avatar simon04 avatar skoging avatar smmoosavi avatar snitin315 avatar sokra avatar timse avatar wgiddens avatar wilfred avatar wuxiandiejia 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  avatar  avatar  avatar

expose-loader's Issues

webpack 4 webpack.config approach doesn't work

  • Operating System: masOs
  • Node Version: 10.x.x
  • NPM Version: 6.x.x
  • webpack Version: 4
  • expose-loader Version: 0.7.5

This issue is for a:

  • bug
  • feature request
  • modification request

Code

CLI Command
  # paste the CLI command you're using. if this isn't applicable, it's safe to remove.
  $ {webpack --env.mode development}

Expected Behavior

Adding this in webpack.config.js should just work:
{ test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' },{ loader: 'expose-loader', options: '$' }] }

Actual Behavior

It doesn't work. (tested it by inspecting angular.js file in the moment it checks for jQuery existence)
The inline version of this approach works fine (but breaks my tests):
import "expose-loader?$!jquery";
import "expose-loader?jQuery!jquery";

Thanks

Babel 6 module.exports syntax

With the introduction of Babel 6 it seems that the exposed syntax has changed, and now instead of receiving the item exported by export default an Object is received with a default key. Assuming it has to do with

http://stackoverflow.com/questions/33505992/babel-6-changes-how-it-exports-default
https://phabricator.babeljs.io/T2212

screen shot 2016-01-04 at 4 14 22 pm

  const babelrc = `{
    "presets": ["react", "es2015", "stage-0"],
    "env": {
      "development": {
        "plugins": [
          "rewire",
          "transform-runtime",
          "transform-decorators-legacy",
          "typecheck",
          ["react-transform",
            {
            "transforms": [{
              "transform": "react-transform-hmr",
              "imports": ["react"],
              "locals": ["module"]
            }, {
              "transform": "react-transform-catch-errors",
              "imports": ["react", "redbox-react"]
            }]
          }]
        ]
      },
      "production": {
        "plugins": [
          "transform-runtime",
          "transform-decorators-legacy",
          "typecheck"
        ]
      }
    }
  }`;

Exposing jQuery not working

In my webpack config I have the following line to expose jQuery on the global scope

{ test: require.resolve('jquery'), loader: 'expose?$!expose?jQuery' },

I have a file that uses the $. For example:

.getScript(`${consumerWebUrl}/scripts/shared/trustlogo.js`)
        .done(() => {
          document.querySelector('#trustlogo_ph').innerHtml($.trustlogo(`${consumerWebUrl}/content/themes/images/trustlogo.png`, 'SC4', 'none'));
        });

However, during my webpack build, get the following error:

error  '$' is not defined  no-undef

Also, if I put the following directly in my file:

require('expose?$!expose?jQuery!jquery');

I get this error:

error  Unable to resolve path to module 'expose?$!expose?jQuery!jquery'  import/no-unresolved

According to this page, the above should all work: https://webpack.github.io/docs/shimming-modules.html. I must be missing something. Any advice?

Doesn't work when used in webpack config (inline works fine)

webpack: 4.19.1
expose-loader: 0.75

This (in my entry file) works fine:

import "expose-loader?$!jquery";
import "expose-loader?jQuery!jquery";

With this (in my webpack.config) doesn't work:
{ test: require.resolve('jquery'), use: [ { loader: 'expose-loader', options: 'jQuery' }, { loader: 'expose-loader', options: '$' } ] }

Push default export to global scope for typescript files

  • Operating System: OS X
  • Node Version: 10.12.0
  • NPM Version: 6.5.0
  • webpack Version: "4.28.0",
  • expose-loader Version: "0.7.5"

This issue is for a:

  • bug
  • feature request
  • modification request

Code

CLI Command
   webpack --mode=development
webpack.config.js
module: {
        rules: [{
                test: /\.ts$/,
                include: path.join(__dirname, "src"),
                loader: "ts-loader"
            },
            {
                type: "javascript/auto",
                test: /\.json$/,
                loader: 'json-loader'
            },
            {
                test: require.resolve('./src/abc/index.ts'),
                loader: 'expose-loader?FP'
            }
        ]
    },
 export default class abc {
    // do something
}

Expected Behavior

abc is added to the global scope or under window

Actual Behavior

Module parse failed: Unexpected token (11:16)
You may need an appropriate loader to handle this file type.

export default class abc {} @ ./src/abc/index.ts-exposed 1:32-55

New Feature Use Case

When trying to use a class inside webpack generated bundle inside another js file (not under the scope of webpack)

Webpack build fails after upgrading to expose-loader 0.7.2

After running npm update, which upgraded expose-loader from 0.7.1 to 0.7.2, I now get the following errror:

ERROR in ./index.jsx
Module parse failed: C:\Projects\MIM\Code\MIM.Web\React\index.jsx Unexpected token (18:4)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (18:4)
    at Parser.pp$4.raise (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:2221:15)
    at Parser.pp.unexpected (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:603:10)
    at Parser.pp$3.parseExprAtom (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1822:12)
    at Parser.pp$3.parseExprSubscripts (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1715:21)
    at Parser.pp$3.parseMaybeUnary (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1692:19)
    at Parser.pp$3.parseExprOps (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1637:21)
    at Parser.pp$3.parseMaybeConditional (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1620:21)
    at Parser.pp$3.parseMaybeAssign (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1597:21)
    at Parser.pp$3.parseParenAndDistinguishExpression (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1861:32)
    at Parser.pp$3.parseExprAtom (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1796:19)
    at Parser.pp$3.parseExprSubscripts (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1715:21)
    at Parser.pp$3.parseMaybeUnary (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1692:19)
    at Parser.pp$3.parseExprOps (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1637:21)
    at Parser.pp$3.parseMaybeConditional (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1620:21)
    at Parser.pp$3.parseMaybeAssign (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1597:21)
    at Parser.pp$1.parseVar (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1034:28)
    at Parser.pp$1.parseVarStatement (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:917:10)
    at Parser.pp$1.parseStatement (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:706:19)
    at Parser.pp$1.parseBlock (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:981:25)
    at Parser.pp$3.parseFunctionBody (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:2105:24)
    at Parser.pp$1.parseFunction (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:1065:10)
    at Parser.pp$1.parseFunctionStatement (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:818:17)
    at Parser.pp$1.parseStatement (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:694:19)
    at Parser.pp$1.parseTopLevel (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:638:25)
    at Parser.parse (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:516:17)
    at Object.parse (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\node_modules\acorn\dist\acorn.js:3098:39)
    at Parser.parse (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\lib\Parser.js:902:15)
    at DependenciesBlock.<anonymous> (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack\lib\NormalModule.js:104:16)
    at DependenciesBlock.onModuleBuild (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack-core\lib\NormalModuleMixin.js:310:10)
    at nextLoader (C:\Projects\MIM\Code\MIM.Web\React\node_modules\webpack-core\lib\NormalModuleMixin.js:275:25)
 @ ./~/expose-loader?mim!./index.jsx 1:33-58
Child extract-text-webpack-plugin:
        + 7 hidden modules

It looks like the change is causing webpack to not pass my file through babel. If I downgrade back to 0.7.1, it starts working as expected. The relevant parts of my webpack.config.js:

module.exports = {
  context: __dirname,

  entry: {
    'app.js': [
      'set-webpack-public-path!',
      'bootstrap-loader',
      'font-awesome-webpack',
      'babel-polyfill',
      'fetch-ie8',

      'expose?mim!./index',
    ],
  },

  module: {
    loaders: [
      {
        test: /\.(jsx|js)$/,
        exclude: /node_modules/,
        loader: 'babel-loader?cacheDirectory',
      },
      //...
    ],
  },

  resolve: {
    extensions: ['', '.js', '.jsx'],
  },
};

Can't expose bluebird using `module.loaders` config in webpack.config.js.

Hi,

For some reason I can't expose bluebird when using this config:

    module: {
        loaders: [
            { test: require.resolve('bluebird'), loader: 'expose?Promise' }
        ]
    }

but everything's fine, when I expose it inline like this:

require('expose?Promise!bluebird');

Do I do anything obviously wrong here?

I prepared a mini-project, that shows the problem: link.

  1. Unzip
  2. npm install
  3. npm run webpack
  4. Open index.html
  5. Open dev tools in the browser and run this in console: Promise.version. It should return a string.
  6. Go back to the source code. Comment out the first line in src/app.js and uncomment the other line.
  7. Uncomment the line webpack.config.js.
  8. Open index.html.
  9. Run this in js console: Promise.version.

Result: It's undefined. Bluebird hasn't been exposed to the global namespace (Chrome uses the native Promise).

Thanks.

jQuery failed to expose after update to 0.7.2

Hi, I face these errors after I update my package to use expose-loader 0.7.2

screen shot 2017-02-14 at 11 07 06 am

I confirmed this because when I revert the version back to 0.7.1, it's working normally again, no errors.

Thank you!

[Bug] Setup via `webpack.config.js` file not working

I am trying to expose jquery to be accessible via $ on external HTML/Browser Console.

The following works:
require("expose-loader?$!jquery");

This doesn't work:

  module: {
    rules: [
      {
        test: require.resolve('jquery'),
        // test: path.resolve(__dirname, 'src/js/jquery.js'),
        // test: "jquery",
        // test: /jquery\.js$/,
        use: [{
            loader: 'expose-loader',
            options: '$'
        }]
      }
    ],
  },

I was wondering did I configure it wrongly.

expose-loader: 0.7.3
webpack: 3.5.1
node: 6.11.2

Can you expose-loader this with ts-loader?

Configuration:

  • index.ts
let foo = "Hello "
let bar = "World";
document.write(_.camelCase(foo + bar))
  • webpack.config.js
module.exports = {
  entry: "./src/index.ts",
  output: {
    filename: "bundle.js"
  },

  resolve: {
    extensions: ['.ts', '.tsx', '.js']
  },
  module: {
    loaders: [{
      test: require.resolve('lodash'),
      loader: 'expose-loader?_'
    }, {
      test: /\.ts$/,
      loader: 'ts-loader'
    }]
  }
}

Expected behavior:

  • get a compiled file called bundle.js

Actual behavior:

ERROR in ./src/index.ts
(6,16): error TS2686: '_' refers to a UMD global, but the current file is a module. Consider adding an import instead.

Setup via `webpack.config.js` file not working with NamedModulesPlugin

Reproduction - https://github.com/WiseBird/expose_loader_named_modules_plugin

I use expose-loader to expose jquery:

            {
                test: require.resolve('jquery'),
                use: [{
                    loader: 'expose-loader',
                    options: 'jQuery'
                }]
},

It works without NamedModulesPlugin while producing next output:

/* 88 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(global) {module.exports = global["jQuery"] = __webpack_require__(89);
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)))

/***/ }),
/* 89 */
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
 * jQuery JavaScript Library v3.2.1
...

when NamedModulesPlugin is included output is following:

/***/ "./node_modules/jquery/dist/jquery.js":
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(global) {module.exports = global["jQuery"] = __webpack_require__("./node_modules/jquery/dist/jquery.js");
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__("./node_modules/webpack/buildin/global.js")))

/***/ }),

/***/ "./node_modules/jquery/dist/jquery.js":
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
 * jQuery JavaScript Library v3.2.1

So both modules: the one exposing jquery and the one containing jquery have the same name.

Moreover when exposing via require('expose-loader?jQuery!jquery'); the module exposing jquery have different name:

/***/ "./node_modules/expose-loader/index.js?jQuery!./node_modules/jquery/dist/jquery.js":
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(global) {module.exports = global["jQuery"] = __webpack_require__("./node_modules/jquery/dist/jquery.js");
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__("./node_modules/webpack/buildin/global.js")))

/***/ }),

NamedModulesPlugin uses libIdent from NormalModule that in its order uses userRequest that differs when library exposed via config file or via require statement.

doc: Please add an example how to export functions/classes from my own lib

I want to expose some of my TS-classes to 'window' but I have no idea how to automate this process with expose-loader...

At the moment I'm doing it manually like so: (exports.ts)
(just in case someone else has the same problem...)

import { Name as NameToExport } from "./address/Name";
import {
    addValues as addValuesToExport,
    sayMyName as sayMyNameToExport,
} from "./index";

declare global {
    namespace MyLib {
        export type Name = NameToExport;
        export const Name: typeof NameToExport;

        export const addValues: typeof addValuesToExport;
        export const sayMyName: typeof sayMyNameToExport;
    }
}

(window as any).MyLib = {
    Name: NameToExport,
    addValues: addValuesToExport,
    sayMyName: sayMyNameToExport,
};

I'm using webpack 4 and TS 3

Something weird in deal multiple local version and global version of webpack and webpack-dev-server

  • Operating System: not related to this issue
  • Node Version: not related to this issue
  • NPM Version: not related to this issue
  • webpack Version: not related to this issue
  • expose-loader Version: not related to this issue

This issue is for a:

  • bug
  • feature request
  • modification request

Code

CLI Command
  # paste the CLI command you're using. if this isn't applicable, it's safe to remove.
  webpack [...something]
  webpack-dev-server [...something]

Expected Behavior

if i have install two mudules with their dirrerent version of webpack :

in node_modules it will like this

ROOT
|-node_modules
    |-modA
    |-modB
    |    |-node_modules
    |       |[email protected]
    |[email protected]

it is because of the modules management way of npm

If there is no accident, when i call modA it use [email protected], modB use @3.6.0. but in fact it all use [email protected](it wil bring Bug, if there is no accident:joy:)

so i find the way to check if there is webpack installed in second dependencies(like [email protected] above):smirk:

that is what i do:

// call [email protected] in modB/index.js
const path = require('path')

const LOCAL = path.resolve(__dirname)

const getLocalPath = (packageName) => {
  let res
  // try to find local webpack version
  try {
    const localWebpack = require.resolve(path.join(LOCAL, 'node_modules', '.bin', packageName))
    if (localWebpack) {
      res = localWebpack
    } else {
      res = require.resolve(packageName)
    }
  } catch (e) { }
  console.log(`res: ${res}`)
  return res
}

const WEBPACK_BIN = getLocalPath('webpack')

// ไฝฟ็”จ webpack ่ฟ›่กŒๆœฌๅœฐๅผ€ๅ‘
program
  .command('compile [dir]')
  .description('run project on development mode')
  .action((dir, options) => {
    const wpConfDev = path.resolve(__dirname, './webpack.config.dev.js')
    let opt = ['--config', wpConfDev]
    spawn.sync(
      WEBPACK_BIN,
      opt,
      {
        stdio: 'inherit',
        cwd: projectCwd,
      },
    )
  })

thank god, i can locate to the ROOT/node_modules/modB/node_modules/.bin/[email protected] when i call modB

but ๐Ÿ˜ต

the code in ROOT/node_modules/modB/node_modules/[email protected]/bin/webpack.js get me back again

...
// Local version replace global one
try {
  var localWebpack = require.resolve(path.join(process.cwd(), "node_modules", "webpack", "bin", "webpack.js"));
  if(__filename !== localWebpack) {
    return require(localWebpack);
  }
} catch(e) {}
...

it locate me back to the ROOT/node_module/[email protected]/bin/webpack.js

it may lack the logic branch to check if there is webpack installed in second dependencies

that is my way to solute it:

...
var ifOutOfLocal = function () {
  var relate = path.relative(path.join(process.cwd(), "node_modules"), __filename).split(path.sep)
  var ifOut = false
  for (var i = 0; i < relate.length; i++) {
    var match = relate[i].match(/\.\./)
    if (match) {
      ifOut = true
      break
    }
  }
  return ifOut
}

// Local version replace global one
try {
  var localWebpack = require.resolve(path.join(process.cwd(), "node_modules", "webpack", "bin", "webpack.js"));
  var ifOut = ifOutOfLocal()
  if (__filename !== localWebpack && ifOut) {
    return require(localWebpack);
  }
} catch (e) { }
...

i find it work for me in this issue, and i found it appear in lost of version of webpack(v2 and v3) and webpack-dev-server(v2 and v3)

if this modification is ok, i will make a pull of them.

Thanks for reading, my English is not very good.:smile:

Actual Behavior

How Do We Reproduce?

New Feature Use Case

issue with dll plugin

Hi, I got a problem when use expose and dll plugin at the same time, when I put the jquery in dll plugin, it will not work.

If I don't use dll plugin, it can work well both use require('expose?jQuery!jquery') and write it in webpack config file.

But since I put jquery in dll plugin, it can only work by using require('expose?jQuery!jquery'). If I write the jquery loader in config file, it will not work. All the code is the same, except I write a dll plugin.

splitChunks won't expose given expose-loader rules

  • Operating System: Linux Ubuntu 16
  • Node Version: v8.12.0
  • NPM Version: 6.6.0
  • webpack Version: 4.29
  • expose-loader Version: 0.7.5

This issue is for a:

  • bug
  • feature request
  • modification request

Code

webpack.config.js (splitchunks)
  optimization: {
    noEmitOnErrors: true,
    nodeEnv: 'development',
    runtimeChunk: 'single',
    splitChunks: {
      chunks(chunk) {
        return mainLayouts.includes(chunk.name);
      },
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors-layout',
          enforce: true,
        },
      }
  }
webpack.config.js (expose-loader rules)
  {
        test: require.resolve('jquery'),
        use: [{
          loader: 'expose-loader',
          options: 'window.jQuery',
        },
        {
          loader: 'expose-loader',
          options: 'jQuery',
        }, {
          loader: 'expose-loader',
          options: '$',
        }],
    }

Expected Behavior

When I splitchunks for vendors (ej. jquery) and add this bundle to my template as well as its own template bundle, globals variables are not accesible.
If I DON'T splitChunks, expose-loader exports correctly the variable. I'm getting crazy wondering what the hell I'm doing bad.

I have 4 templates chunks with its own bundle, and I wanted to extract common libraries to a vendros-layout bundle. I managed to splitted but the things seem to change.

Actual Behavior

jQuery is not accesible when splitt vendors bundle. If I do not split it, jQuery is accesible in the same layout it was not on the split process.

How Do We Reproduce?

templateA.pug --> vendors-layout.js (splitted bundle), templateA-bundle.js (specific template bundle)
templateB.pug -> vendors-layout.js (splitted bundle), templateB-bundle (specific template bundle)
templateA.js -> require('jquery'), requires of specific libraries for template (some use jQuery global expose)
templateB.js -> require('jquery'), requires of specific libraries for template (some use jQuery global expose)

With split strategy of Webpack 4, vendors-layout won't expose correctly jQuery, and because of that next bundle libraries won't be able to access jQuery variable on the scope.
Disabling vendors-layout it works.

webpack 4

is this module going to be updated for use with webpack 4 with #61 ?

NamedModulesPlugin breaks expose-loader from exposing the variable globally

The desired setup would be to have jquery exposed globally for plugins that require it (using expose-loader). HMR and NamedModulesPlugin allows for seeing the name of the modules that have been required to be reloaded.

Instead when adding expose-loader and NamedModulesPlugin, the global variable is no longer being added correctly and crashes the application.

Here is a minimal reproduction using jquery and velocity animate:

: https://github.com/NervosaX/webpack-namedmodulesplugin-error

Exposing Modules Imported from Nested Path

Has there been any thought around exposing modules that are imported via a direct path, for example Lodash?

import map from lodash/map

I'm not sure of the best way to do it, or if it is even possible, but it would be a nice addition if so.

The only thing I could come up with is that you could have something ugly like..

global['Lodash'] = {
// ... main lodash export
}

// and then we'd add

global['Lodash']['/map'] = <map function>

Something along those lines. It's definitely not great but I'm curious to hear your thoughts.

how to expose to inline script?

i've a bundle and some functions and i want to be able to expose them to my inline html <script> tag. is it even possible?

Uncaught ReferenceError: global is not defined

I'm using the expose loader like this:

var React = require('expose?React!react');

With the following webpack.config:

module.exports = {
    entry: 'app.js',
    output: {
        path: path.join(__dirname, 'dist/www'),
        filename: '[chunkhash].entry.js',
        chunkFilename: '[chunkhash].[name].js'
    },
    module: {
        noParse: /bower_components/,
        loaders: [
            // { test: require.resolve('react'), loader: 'expose?React' },
            { test: /\.js$/, loader: 'jsx-loader?harmony' },
            { test: /\.css$/, loader: 'style-loader!css-loader' },
            { test: /\.(png|jpg|gif)$/, loader: 'url-loader?limit=8192' }
        ]
    },
    resolve: {
        root: [
            path.join(__dirname, 'www/bower_components'),
            path.join(__dirname, 'www/app'),
            path.join(__dirname, 'www/assets')
        ]
    },
    plugins: [
        new webpack.ResolverPlugin(
            new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin('bower.json', ['main'])
        ),
        new StatsPlugin(path.join(__dirname, 'dist/server', 'stats.json'), {
            chunkModules: true
        })
    ]
};

The module compiles down to:

module.exports = global["React"] = require("-!/Users/Rich/Projects/react-webpack-boilerplate/node_modules/jsx-loader/index.js?harmony!/Users/Rich/Projects/react-webpack-boilerplate/www/bower_components/react/react.js");

so even if I change global to window it'll error out on the require call.

What I imagine it should compile down to is:

module.exports = window["React"] = __webpack_require__(10); // or whatever the react id is.

I'm struggling to work out how I'd achieve this or what I'm doing wrong, any ideas?

webpack-defaults upgrade

Addition of webpack-defaults & associated refactoring as a part of the next Major release

Issue exists for status tracking across the organization.

Please do not close

Exposing jquery-ui-bundle with jquery

Hello.

Works great for exposing jquery and moment, but how do I append jquery-ui-bundle to $ and jquery and moment-timezone to moment?

Same goes for everything that have separate locale files.

How can I expose nameless javascript like locale, and library that depend on others like jquery and moment?

Expose Loader not exposing all attributes

Expose Loader does not correctly expose all the attributes of a module.

This issue is for a:

  • bug
  • feature request
  • modification request

Code

https://codesandbox.io/s/nw4pk93jm - The sample shows the case where, when a module made available without webpack/expose-loader, all the properties/functions are available.

https://codesandbox.io/s/l9q9z541k9 - The sample shows the case where, when a module made available with webpack/expose-loader, only some properties/functions are available.

Expected Behavior

Same/All attributes should be available with and without Webpack/Expose-loader.

can not export vuex with webpack config

  • Operating System: Mac
  • Node Version: 10.0.0
  • NPM Version: 5.6.0
  • webpack Version: 4.5.0
  • expose-loader Version: 0.7.5

This issue is for a:

  • bug export-loader not work with vuex

Code

when i import 'vuex' and import 'jquery' window.vuex is not defined, but window.$ can be use correct

when i use import 'expose-loader?vuex!vuex', window.vuex can be use.

      // webpack loader config
      {
        test: require.resolve('vuex'),
        use: [{
          loader: 'expose-loader',
          options: 'vuex'
        }]
      },
      {
        test: require.resolve('jquery'),
        use: [{
           loader: 'expose-loader',
           options: 'jQuery'
        },{
           loader: 'expose-loader',
           options: '$'
        }]
      },
CLI Command
  # paste the CLI command you're using. if this isn't applicable, it's safe to remove.
  $ {the command}
webpack.config.js

https://github.com/Val-istar-Guo/assist/blob/dad23f08212c818b4fd210036a656cd77a02b149/build/webpack.config.common.js#L26-L52

https://github.com/Val-istar-Guo/assist/blob/dad23f08212c818b4fd210036a656cd77a02b149/client/store/index.js#L6-L7

Expected Behavior

window.vuex can be use, when import vuex and use webpack configใ€‚

Actual Behavior

can not find vuex, unless import 'expose-loader?vuex!vuex'

[Refactor] Support exposing ESM without `harmony` export

I'm using expose-loader to expose some ES6 modules, which are currently using export default {...}, however instead of getting the resource at my exposed variable, it's at module.default. Here's my require:

require("expose-loader?Store!./store/index.js");

And here's my export:

export default new Vuex.Store({
...
})

My module is now exposed at Store.default.

Is this just a side effect of ES6 modules or is there a way to expose the default directly on the variable?

what is wrong with this webpack2 expose-loader config?

I am attempting to consume react-handsontable which recommends using expose-loader to make some dependencies available on the global scope.
https://github.com/handsontable/react-handsontable/wiki/Installation-guide#hot-ce-webpack

I have this issue
https://github.com/handsontable/react-handsontable/issues/11

which may just be my ignorance in configuring expose-loader.

from the issue above:
relevant part of webpack config looks like

 {
    test: require.resolve('handsontable'),
    loader: 'expose-loader?Handsontable'
  },
  {
    test: require.resolve('numbro'),
    loader: 'expose-loader?numbro',
    //options: {'numbro': null}
  },
  {
    test: require.resolve('moment'),
    loader: 'expose-loader?moment'
  },
  {
    test: require.resolve('pikaday'),
    loader: 'expose-loader?Pikaday'
  },
  {
    test: require.resolve('zeroclipboard'),
    loader: 'expose-loader?ZeroClipboard'
  },

inside the relevant react component I import as outlined by the docs:

import moment from 'moment';
import numbro from 'numbro';
import pikaday from 'pikaday';
import Zeroclipboard from 'zeroclipboard';
import Handsontable from 'handsontable';
import HotTable from 'react-handsontable';
import 'handsontable/dist/handsontable.full.css';

but if i do window.numbro I can see that it is undefined.

If i understand correctly, i expect window.numbro to be my numbro import. Is this correct?
If yes, what is going wrong?
if not, how do i test that expose-loader is doing what it should be doing?

Does not work on Windows 10 OS?

First here's my webpack.config.js:

        test: /assets\/lib\/babylon.js/,
        use: [
          {
            loader: 'expose-loader',
            query: 'BABYLON'
          }
        ]

Then I found a weird thing, with a totally same project and its code:

  • After building on Windows 10 OS, window.BABYLON is not defined.
  • But after building on Mac or Linux, window.BABYLON is OK.

Issue with expose-loader

I have a react component which is written in ES6. I have used babel/webpack to transpile it and generate a index.js file. I noticed that the resulting React Component is wrapped in a function and I cannot use it externally. I am trying to use it a different angular controller. I am trying to use webpack expose-loader but I still see undefined for the locally scoped vars.

webpack.config.js(snippet)

    module: {
    loaders: [
        {
            test: /.jsx?$/,
            exclude: /node_modules/,
            loader: 'babel',

            query: {
                presets: [ 'react', 'es2015']
            }
        },
        {
            test: require.resolve("react"), loader: "expose?React" ,
            query: {
                presets: [ 'react', 'es2015']
            }
        }
    ]
}
}

WebPack (AppList is my react component)-Snippet

/***/ function(module, exports, webpack_require) {

'use strict';

var _react = __webpack_require__(2);

var _react2 = _interopRequireDefault(_react);

var _reactDom = __webpack_require__(36);

var _reactDom2 = _interopRequireDefault(_reactDom);

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

var AppList = _react2.default.createClass({
    displayName: 'AppList',

    propTypes: {},

    render: function render() {
        return _react2.default.createElement(
            'div',
            null,
            'appList '
        );
    }
});
module.exports = AppList;
/***/ },

Can anyone please help here?

jQuery and moment work unless explicitly set to window in entry.js

I get

Uncaught ReferenceError: jQuery is not defined

If I do:

require("expose?$!jquery");
require('expose?moment!moment');

But when I write it out like this:

var $ = require('jquery');
window.jQuery = $;
window.$ = $;
var moment = require('moment');
window.moment = moment;

It seems to work fine. Is there a reason for this

issue with jquery ....

We are using webpack 3:

Here are our config:

/*
    Imports
*/

import webpack from 'webpack';
import path from 'path';
import DashboardPlugin from 'webpack-dashboard/plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';


/*
    Useful constants
*/

const SITE_NAME = path.basename(path.join(__dirname, '/../../'));
const THEME_NAME = path.basename(__dirname);

/*
    Plugin configuration
*/

//different css points
const extractEditor = new ExtractTextPlugin({
    filename: 'css/editor.css',
});
const extractMain = new ExtractTextPlugin({
    filename: 'css/style.css',
});

//define plugins
let plugins = [];

const IS_PROD = process.env.NODE_ENV === 'production';

if(IS_PROD) {
    plugins.push(
        new webpack.optimize.UglifyJsPlugin(),
        extractEditor,
        extractMain
    );


//development
} else {
    plugins.push(
        //auto updating on dev server
        new webpack.HotModuleReplacementPlugin(),
        //shows relative path in HotModuleReplacement
        new webpack.NamedModulesPlugin(),
        //sexy dashboard
        new DashboardPlugin(),
        extractEditor
    );
}

plugins.push(new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery",
        "window.jQuery": "jquery"
}))

const sources = [`../${THEME_NAME}_base/src`, `../${THEME_NAME}_mysite/src`];

const sassFolders = sources.map((source) => path.resolve(source, "scss"))
    .concat(sources.map((source) => path.resolve(source, "sass")));

//HMR can be fixed by using basic loaders instead of textExtract
const sassLoaderExtract =    {
    fallback: 'style-loader',
    use: [
        'css-loader',
        {
            loader: 'postcss-loader',
            options: {
                sourceMap: true
            }
        },
        {
            loader: 'sass-loader',
            options: {
                sourceMap: true
            }
        },
    ]
}

const styleLoaders = [{
    //basic css
    test: /\.css/i,
    use: ['style-loader', 'css-loader']
}, {
    //main styles
    test: /[^editor].\.s(a|c)ss$/i,
    include: sassFolders,
    use: extractMain.extract(sassLoaderExtract)
}, {
    //styles for editor
    test: /editor\.s(a|c)ss/i,
    include: sassFolders,
    use: extractEditor.extract(sassLoaderExtract)
}];

const jsLoaders = [
    // KEEP THE CODE BELOW AND TURN ON IF NEEDED....
    // {
    //     //eslint check
    //     enforce: 'pre',
    //     test: /\.js$/i,
    //     exclude: /node_modules/,
    //     use: {
    //         loader: 'eslint-loader'
    //     }
    // },
    {
        //js compilation
        test: /\.js$/i,
        include: sources.map((source) => path.resolve(source, "src")),
        exclude: /node_modules/,
        use: {
            loader: 'babel-loader',
            options: {
                cacheDirectory: true,
                presets: [require.resolve("babel-preset-es2015")]
            }
        }
    },
    {
        test: require.resolve('jquery'),
        use: [{
            loader: 'expose-loader',
            options: 'jQuery'
        },{
            loader: 'expose-loader',
            options: '$'
        }]
    }
];

const imageLoaders = [
    {
        test: /\.(png|jpg|gif)$/i,
        include: sources.map((source) => path.resolve(source, "images")),
        use: [
            {
                loader: 'url-loader',
                options: {
                    limit: 30000,
                    name: 'images/[name].[ext]'
                }
            },
            {
                loader: 'image-webpack-loader',
                options: {
                    optipng: {
                        optimizationLevel: 5
                    },
                    mozjpeg: {
                        interlaced: true,
                    }
                }
            }
        ]
    },
    {
        test: /\.svg$/i,
        use: 'svg-inline-loadera'
    }
];

/*
    Main Config Object
*/
export default {
    //what files to start from
    //bundle should include main.js from all sources
    entry: path.resolve(`../${THEME_NAME}_mysite/src`, "main.js"),
    //access from client
    output: {
        path: path.resolve(`../${THEME_NAME}_dist/`, ''),
        publicPath: `/themes/${THEME_NAME}_dist/`,
        filename: 'bundle.js'
    },
    //loaders
    module: {
        rules: styleLoaders.concat(jsLoaders).concat(imageLoaders)
    },
    //extra settings
    resolve: {
        modules: [
            path.join(__dirname, "node_modules"),
        ],
        alias: {
            base: path.resolve(`../${THEME_NAME}_base/src/`),
            'jquery': 'jquery/dist/jquery',
            'jQuery': 'jquery/dist/jquery'
        },
        extensions: [".js", ".jsx"]
    },
    devServer: {
        disableHostCheck: true,
        host: '0.0.0.0',
        hot: true,
        port: 3000,
        publicPath: `/themes/${THEME_NAME}_dist/`,
        proxy: {
            '/': {
                'target': {
                    'host': `${SITE_NAME}.localhost`,
                    'protocol': 'http',
                    'port': 80
                },
                changeOrigin: true,
                secure: false
            }
        },
        stats: 'errors-only'
    },
    plugins: plugins
};

in main.js we have:

import $ from 'jquery';

Works fine on build, but it does not work fine when NPM is watching / running (jquery is NOT recognised inside webpack nor outside of it at all).

Any ideas?

0.7.4 not compatible with webpack v1

Looks like in the recent 0.7.4 release peerDependencies: {"webpack": "^2.0.0 || ^3.0.0"} has been added - effectively marking the plugin incompatible with webpack v1.

Is there any change in the code that really makes the module incompatible with v1? It doesn't seem to be the case based on the diff (v0.7.3...v0.7.4) - but maybe I'm missing something?
Also the readme file still contains instructions for webpack v1 usage.

Is it possible to update peerDependencies to allow webpack v1?

Any way to expose when not in the bundle?

I'd like to be able to expose a library using the loader, but suppose that library is not directly referenced. I'm guessing I can make an entry point, but I was wondering if a param could be added to the loader to always put in the library.

The react-router-dom,react-redux,redux is packaged invalid in webpack V3.

When a package is exposed as a global variable in the react project, the same configuration react-router-dom,react-redux, and redux are not valid when packaged.
Attach a code:
module: { rules: [ { test: /\.(js|jsx|es6)$/, exclude: /node_modules/, use: 'babel-loader' }, { test: /\.less$/, use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'] }, { test: /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader'] }, { test: /\.(jpg|jpeg|gif|bmp|png)$/, use: { loader: 'url-loader', options: { limit: 8192, name: 'assets/images/[name].[ext]' } } }, { test: /\.(woff|woff2|eot|svg|ttf)($|\?)/, use: { loader: 'url-loader', options: { limit: 8192, name: 'assets/fonts/[name].[ext]' } } }, { test: require.resolve("react"), use: [ { loader: 'expose-loader', options: 'React' } ] }, { test: require.resolve("react-addons-pure-render-mixin"), use: [ { loader: 'expose-loader', options: 'PureRenderMixin' } ] }, { test: require.resolve("react-router-dom"), use: [ { loader: 'expose-loader', options: 'ReactRouter' } ] }, { test: require.resolve("react-redux"), use: [ { loader: 'expose-loader', options: 'ReactRedux' } ] }, { test: require.resolve("redux"), use: [ { loader: 'expose-loader', options: 'Redux' } ] }, { test: require.resolve("react-dom"), use: [ { loader: 'expose-loader', options: 'ReactDom' } ] } ] }
Excuse me what method solves, what reason causes?

Project description in the README

It would be useful for first time visiters to https://github.com/webpack-contrib/expose-loader to explain what expose-loader does.

The npmjs page does a decent job with "The expose loader adds modules to the global object. This is useful for debugging, or supporting libraries that depend on libraries in globals."

(see https://www.npmjs.com/package/expose-loader)

The README could do with an explaination about what the project does.

I hope this doesn't come across as flippant.. Thank you for your work!

Exposing modules which augment existing objects

So I currently use Sugar.js internally in a library (webpack outputs as a library) and sugar just extends native objects so there is no object returned from its require, i.e:

require("sugar");

var value = "hello {1}".assign("bob");

So in these scenarios how can I get it to expose this module when it does not return anything?

Not able to expose the variable with dot in its name

Hi guys, let's say I have a js file with dot in its name, e.g xyz.template.js. And I want to expose it into my global variable modules => modules['xyz.template.js'].

According to the source code below(value.split(".")), it is not possible to expose a variable which name contains 'dot'. I think it should be able to do that,

 function accesorString(value) {
    var childProperties = value.split(".");  // Not able to expose 'xyz.template'  
    var length = childProperties.length;
    var propertyString = "global";
    var result = "";

    for(var i = 0; i < length; i++) {
        if(i > 0)
            result += "if(!" + propertyString + ") " + propertyString + " = {};\n";
        propertyString += "[" + JSON.stringify(childProperties[i]) + "]";
    }

    result += "module.exports = " + propertyString;
    return result;
}

Please correct me if I was wrong about this.

Exposing JSX Components

So I am trying to expose all my React components in the bundle to global of the browser (window). I am using the webpack's expose-loader to do so.

I have full success in exposing plain JS modules but when I try to expose JSX modules, it gives me an error:

Module parse failed: ~/project/src/components/list.jsx Line 20: Unexpected token <
You may need an appropriate loader to handle this file type.
...

The error only shows up for the 3rd loader entry that uses expose. If that loaders entry is removed, React components build just fine.

Here's the webpack config file:

module.exports = {
  entry: "./src/components/index.js",

  output: {
    filename: "bundle.js",
    path: __dirname + "/web"
  },

  module: {
    loaders: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        loaders: ["babel-loader?presets[]=react,presets[]=es2015"],
      },
      {
        test: require.resolve("react"),
        loader: "expose?React"
      },
      {
        test: /list.jsx$/,
        loaders: ["babel-loader?presets[]=react,presets[]=es2015", "expose?List"]
      }
    ]
  }
};

I have tried to use babel-loader before the expose loader to try to fix the error but no luck, same error. Has anyone had any success exposing React components globally using web pack before.

Source Maps Not Generated

It seems as though source maps for my exposed file don't get generated properly:

loaders: [{
   test: require.resolve('./index.js'),
   loaders: ['expose?MyProject', 'babel-loader']
}]

The generated source map looks like this (using cheap-module-eval-source-map), which does not match the contents of index.js

module.exports = global["MyProject"] = require("-!/{...}/node_modules/babel-loader/index.js!/{...}/index.js");

/** WEBPACK FOOTER **
 ** index.js
 **/

Clarify/improve config usages in readme

Readme suggests require.resolve as a way to get path to a module, but webpack's resolution differs from node's one (e.g. webpack supports module property).

Please update readme with info about how to properly get module path.

0.7.2: webpack no longer traverses project

Hello! Apologies if I'm raising this in the wrong place, but my build has started failing, and it looks like it's related to the recent 0.7.2 release of expose-loader.

FWIW, my build is now failing because UglifyJS is claiming there's a syntax error, specifically Unexpected token: punc({).

I think that's a bit of a red herring, though: UglifyJS is choking on an export {Foo} from './bar' line in the JS that webpack is producing when I used 0.7.2, but which is absent when I use 0.7.1. In fact, when I use 0.7.2, webpack seems to be emitting only a single module, which is my Scripts/index.ts (which contains the exports that UglifyJS doesn't like); when I use 0.7.1, webpack seemingly correctly traverses the project from index.ts and emits all the modules I'd expect from my project.

My only use of expose-loader is in the single entry point I have in webpack.config.js:

{
    entry: {
        myproj: 'expose?Myproj!./Scripts'
    }
}

I'm not especially familiar with webpack, so please let me know if you need any more information from me to diagnose this, or if you think my webpack config is inherently wrong in some way!

Thanks,
Rowan

Simple use case doesn't work :(

Hi webpack guys,
I'm struggling with this tool, I've just followed your basic instructions but no way to access window.libraryName

This is my file.js

var a="saludo";
console.log(a);
module.exports={"saludo":a};

This is my expose-loader call

require("expose?libraryName!./file.js");

And this is the result I get :

screen shot 2015-03-16 at 17 19 40

Thanks in advance!
Juan

Expose Order?

I have a common bundle like this:

common: ['expose?jQuery!jquery', 'expose?angular!angular', 'angular-ui-router', 'angular-animate', 'angular-sanitize']

I also extend it like new webpack.optimize.CommonsChunkPlugin 'common', 'common/common.js'

It seems like angular isn't exposed before angular-ui-router runs, causing an error.

Taking everything angular-related out of the common bundle and using ProvidePlugin works for some reason, but I would like to have an explicit common bundle.

Please provide example for Webpack 2 syntax

For example something like this. It would be very helpful if two Webpack 2 examples could be given for something like this with 1 and 2 exposes.

{
  test: /jquery\.js$/,
  loader: "expose?jQuery!expose?$"
}

Expose after imports does not work, plugins order issue

Webpack v1.13.3

OK

This does work and this inside Backbone becomes window.

{ test: /backbone/, loader: 'imports?this=>window,$=jquery,_=underscore' },

Compiled source:

...
	}).call(undefined);
	}.call(window));

Error

This does now work because this inside Backbone is undefined.

{ test: /backbone/, loader: 'imports?this=>window,$=jquery,_=underscore!expose?Backbone' },

Compiled source (no second }.call(window))):

...
	}).call(undefined);

OK โ„–2

If plugins order changed and expose put first it works

{ test: /backbone/, loader: 'expose?Backbone!imports?this=>window,$=jquery,_=underscore' },

Compatibility with webpack/webpacker 3?

This doesn't appear to be working correctly with the latest webpacker/rails setup, has it been tested with webpack 3? We are using the require format like this:

require('expose-loader?$!jquery')

And not seeing a global $ defined

Expose without libraryName

Is it possible to export all namespaces of a file without a libraryName?

Consider this example:
_Public.ts
import { MyClass } from 'MyClass'; export namespace MyNamespace { export const Class = MyClass; }

And this expose-loader:
require("expose-loader?!xxx./_Public"); // what to use here?

How can I export the MyNamespace to the global scope without specifying an additional libraryName? So I can use MyNamespace.Class from global.

I know I could remove the namespace declaration and expose MyNamespace as libraryName, but that's no use for me.

Multiple Expose?

e.g.

in webpack 's config file, how to expose jquery as jQuery and $?
have to write tow loader?

Problem with react-phoenix, webpack 3

I believe this is just the expose-loader-is-silently-broken-under-Webpack-3 issue we've been seeing crop up elsewhere in Issues, but just in case it isn't;

I have a Phoenix/Elixir app that uses a React/ES6 frontend. Currently we're using Brunch and it sucks. I got everything configured for webpack, however, but now there's trouble.

The module react-phoenix, which we depend on to inject react into phoenix .eex templates, works by rendering react components attached to window. In this case, the app name is Spark, so under brunch we attached window.Spark.Foo, where Foo is the component to be rendered on, say, foo.html.eex, and we were off to the races.

With Webpack, though, it appears that I need to attached Spark to window with expose-loader. Why isn't expose-loader working given the webpack.config below?

Our webpack looks like this:

const path = require('path')
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')


module.exports = (env) => {
  const isDev = !(env && env.prod)
  const devtool = isDev ? 'eval' : 'source-map'

  return {
    devtool,

    context: __dirname,

    entry: {
      app: [
        'babel-polyfill',
        'react-hot-loader/patch',
        'js/spark.js',
        'react-phoenix',
        'stylus/app.styl',
      ],
    },

    output: {
      path: path.resolve(__dirname, '../priv/static'),
      filename: 'js/[name].js',
      publicPath: 'http://localhost:8080/',
    },

    devServer: {
      headers: {
        'Access-Control-Allow-Origin': '*',
      },
    },

    module: {
      rules: [
        {
          test: /\.(jsx?)$/,
          exclude: /node_modules/,
          loader: 'babel-loader',
        },

        {
          test: /\.(gif|png|jpe?g|svg)$/i,
          exclude: /node_modules/,
          loaders: [
            'file-loader?name=images/[name].[ext]',
            {
              loader: 'image-webpack-loader',
              options: {
                query: {
                  mozjpeg: {
                    progressive: true,
                  },
                  gifsicle: {
                    interlaced: true,
                  },
                  optipng: {
                    optimizationLevel: 7,
                  },
                  pngquant: {
                    quality: '65-90',
                    speed: 4,
                  },
                },
              },
            },
          ],
        },
        {
          test: /js\/spark.js$/,
          use: [{
            loader: 'expose-loader',
            options: 'Spark',
          }],
        },
        {
          test: /\.(css|styl)$/,
          exclude: /node_modules/,
          use: isDev ? [
            'style-loader',
            'css-loader',
            'postcss-loader',
            'stylus-loader',
          ] : ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: ['css-loader', 'postcss-loader', 'stylus-loader'],
          }),
        },
      ],
    },

    resolve: {
      modules: ['node_modules', __dirname],
      extensions: ['.js', '.json', '.jsx', '.css', '.styl'],
    },

    plugins: isDev ? [
      new CopyWebpackPlugin([{
        from: './static',
        to: path.resolve(__dirname, '../priv/static'),
      }]),
    ] : [
      new CopyWebpackPlugin([{
        from: './static',
        to: path.resolve(__dirname, '../priv/static'),
      }]),

      new ExtractTextPlugin({
        filename: 'css/[name].css',
        allChunks: true,
      }),

      new webpack.optimize.UglifyJsPlugin({
        sourceMap: true,
        beautify: false,
        comments: false,
        extractComments: false,
        compress: {
          warnings: false,
          drop_console: true,
        },
        mangle: {
          except: ['$'],
          screw_ie8 : true, // eslint-disable-line
          keep_fnames: true,
        },
      }),
    ],
  }
}

And spark.js looks like:

import page from './registry'
import { isProd } from './util'
import { client } from './apollo'

export default { page, client, isProd } // eslint-disable-line

expose ES6 modules

When exposing an es6 module i get a global object with a property named default which represents the export.

I would like to be able to skip this wrapper and have the global variable = default export. no abstraction/wrapper.

As it stands I find myself creating intermediate modules with the following syntax
module.exports = require('./filename').default;

and then
require('expose-loader?LibraryName!./intermediateFile');

Is there a simple solution to this problem?
If not, are there any plans for a fix?

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.