admin管理员组文章数量:1399994
I tried this the last two days and I can't get it to work like expected: I want to build my own JavaScript library and register it under an already existing namespace ("OCA" - in this particular case). And as you might understand, I don't want to be forced to go without modern approaches like type safety through typescript or modules.
Therefore I use webpack 2 and the libraryTarget: umd
to register the output under "OCA.Ocr" (my library is named "Ocr"). This works like intended, but when it es to the point that I want to use for example underscorejs, as it will be available globally in the application the library should be also delivered to, I cannot get it to work.
I followed the webpack configuration documentation and it says that the externals configuration option should be the way to go:
externals: { // object
angular: "this angular", // this["angular"]
react: { // UMD
monjs: "react",
monjs2: "react",
amd: "react",
root: "React"
}
}
// Don't follow/bundle these modules, but request them at runtime from the environment
I used it like proposed by the guide but it doesn't work:
/* global __dirname, require, module*/
const webpack = require("webpack");
const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
const path = require("path");
module.exports = function (env) {
let target = env.target;
let libraryName = ["OCA", "Ocr"];
let plugins = [];
let outputFile;
if (target === "production") {
plugins.push(new UglifyJsPlugin({ minimize: true }));
}
outputFile = "ocr[name].min.js";
const config = {
entry: {
app: __dirname + "/src/app.ts",
personal: __dirname + "/src/personal.ts"
},
output: {
path: __dirname + "/dist",
filename: outputFile,
library: libraryName,
libraryTarget: "umd",
umdNamedDefine: true
},
module: {
rules: [
{
test: /\.ts$/,
enforce: "pre",
loader: "tslint-loader",
options: {
tsConfigFile: "tsconfig.app.json",
}
},
{
test: /\.ts?$/,
loader: "ts-loader",
exclude: /node_modules/,
options: {
configFileName: "tsconfig.app.json"
}
}
],
},
resolve: {
modules: [path.resolve("./src")],
extensions: [".ts"],
},
externals: {
underscore: { // UMD
monjs: "underscore",
monjs2: "underscore",
amd: "underscore",
root: "_"
}
},
plugins: plugins,
};
return config;
}
My app.ts
file which uses the underscore library (for example the _.defer
method, which of course is not always the best to use) looks like that:
import _ from 'underscore';
export class App {
constructor() {
_.defer(() => {
console.log('test');
});
}
}
export let $app: App = new App();
I included it in the application and also checked that the underscorejs library is getting loaded before my lib gets loaded by the browser, but the console output still states:
TypeError: underscore_1.default is undefined
The piled output is the following (maybe this helps a little bit):
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("underscore"));
else if(typeof define === 'function' && define.amd)
define("Ocr", ["underscore"], factory);
else if(typeof exports === 'object')
exports["Ocr"] = factory(require("underscore"));
else
root["OCA"] = root["OCA"] || {}, root["OCA"]["Ocr"] = factory(root["_"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for patibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 2);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */,
/* 1 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_1__;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var underscore_1 = __webpack_require__(1);
var App = (function () {
function App() {
underscore_1.default.defer(function () {
console.log('test');
});
}
return App;
}());
exports.App = App;
exports.$app = new App();
/***/ })
/******/ ]);
});
Does anyone know how this is working and what I will have to do? I am pletely lost and now hoping for your help.
Btw: This is also not working for me.
I tried this the last two days and I can't get it to work like expected: I want to build my own JavaScript library and register it under an already existing namespace ("OCA" - in this particular case). And as you might understand, I don't want to be forced to go without modern approaches like type safety through typescript or modules.
Therefore I use webpack 2 and the libraryTarget: umd
to register the output under "OCA.Ocr" (my library is named "Ocr"). This works like intended, but when it es to the point that I want to use for example underscorejs, as it will be available globally in the application the library should be also delivered to, I cannot get it to work.
I followed the webpack configuration documentation and it says that the externals configuration option should be the way to go:
externals: { // object
angular: "this angular", // this["angular"]
react: { // UMD
monjs: "react",
monjs2: "react",
amd: "react",
root: "React"
}
}
// Don't follow/bundle these modules, but request them at runtime from the environment
I used it like proposed by the guide but it doesn't work:
/* global __dirname, require, module*/
const webpack = require("webpack");
const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
const path = require("path");
module.exports = function (env) {
let target = env.target;
let libraryName = ["OCA", "Ocr"];
let plugins = [];
let outputFile;
if (target === "production") {
plugins.push(new UglifyJsPlugin({ minimize: true }));
}
outputFile = "ocr[name].min.js";
const config = {
entry: {
app: __dirname + "/src/app.ts",
personal: __dirname + "/src/personal.ts"
},
output: {
path: __dirname + "/dist",
filename: outputFile,
library: libraryName,
libraryTarget: "umd",
umdNamedDefine: true
},
module: {
rules: [
{
test: /\.ts$/,
enforce: "pre",
loader: "tslint-loader",
options: {
tsConfigFile: "tsconfig.app.json",
}
},
{
test: /\.ts?$/,
loader: "ts-loader",
exclude: /node_modules/,
options: {
configFileName: "tsconfig.app.json"
}
}
],
},
resolve: {
modules: [path.resolve("./src")],
extensions: [".ts"],
},
externals: {
underscore: { // UMD
monjs: "underscore",
monjs2: "underscore",
amd: "underscore",
root: "_"
}
},
plugins: plugins,
};
return config;
}
My app.ts
file which uses the underscore library (for example the _.defer
method, which of course is not always the best to use) looks like that:
import _ from 'underscore';
export class App {
constructor() {
_.defer(() => {
console.log('test');
});
}
}
export let $app: App = new App();
I included it in the application and also checked that the underscorejs library is getting loaded before my lib gets loaded by the browser, but the console output still states:
TypeError: underscore_1.default is undefined
The piled output is the following (maybe this helps a little bit):
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("underscore"));
else if(typeof define === 'function' && define.amd)
define("Ocr", ["underscore"], factory);
else if(typeof exports === 'object')
exports["Ocr"] = factory(require("underscore"));
else
root["OCA"] = root["OCA"] || {}, root["OCA"]["Ocr"] = factory(root["_"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for patibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 2);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */,
/* 1 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_1__;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var underscore_1 = __webpack_require__(1);
var App = (function () {
function App() {
underscore_1.default.defer(function () {
console.log('test');
});
}
return App;
}());
exports.App = App;
exports.$app = new App();
/***/ })
/******/ ]);
});
Does anyone know how this is working and what I will have to do? I am pletely lost and now hoping for your help.
Btw: This is also not working for me.
Share Improve this question edited May 4, 2017 at 18:49 janis91 asked May 4, 2017 at 16:28 janis91janis91 831 silver badge8 bronze badges 2- I also asked this at Github and it turned out, that this is a bug. I will give an update when it's fixed. – janis91 Commented May 9, 2017 at 5:15
- any update? I am also facing same issue with AMD – pathik devani Commented Feb 6, 2018 at 7:02
2 Answers
Reset to default 4I have the same issue as you, however, if you set the property var in the libraryTarget option, the variable stops being undefined. Maybe this will help you:
externals: {
"lodash": {
var:'_'
}
}
You have 2 options here. I remend option #1.
In fact, if you use UMD
and plan on supporting node
(in addition to monjs, amd, and browser), always set globalObject: 'this'
Set output.globalObject
to this
, and use externals.root
.
const config = {
output: {
library: libraryName,
libraryTarget: "umd",
globalObject: 'this' // <-- THIS IS THE IMPORTANT LINE FOR UMD+NODE
},
externals: {
underscore: { // UMD
monjs: "underscore",
monjs2: "underscore",
amd: "underscore",
root: "_"
}
},
};
output.globalObject
When targeting a library, especially when the libraryTarget is 'umd', this option indicates what global object will be used to mount the library. To make UMD build available on both browsers and Node.js, set output.globalObject option to 'this'.
Use externals.var
instead of externals.root
.
externals: {
underscore: { // UMD
monjs: "underscore",
monjs2: "underscore",
amd: "underscore",
var: "_"
}
},
This is a workaround and does not require setting globalObject: 'this'
版权声明:本文标题:javascript - Configuring library as external in webpack does not work with UMD as libraryTarget - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744140014a2592575.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论