If I use imports-loader, what does it mean exports=>false part in configuration? It should inject variable var exports = false, but I don't know when and why I need this variable.
module : {
loaders : [
{
test : /eonasdan-bootstrap-datetimepicker/,
loader : 'imports?define=>false,exports=>false,moment=moment'
}]
}
Imports is for shimming third party code that is expecting global to be defined such as jQuery $ or AMD's define. The reason you might want to do this is because module bundlers often bundle to formats that both AMD and CommonJS understand aka universal module definition UMD format. When importing a UMD module it will first check to see if define (AMD) exists and then exports (CommonJS). Webpack has an easier time parsing CommonJS (nodes native format) so setting define to false explicitly tells webpack to not parse it as an AMD module.
UPDATE
It seems like they are likely disabling all module exports and defining moment as the moment js library. I would guess that the code in that library is extending the bootstrap datepicker control with features from moment.
Related
I understand that Svelte can produce AMD output and find some details on how to do this in the docs. I can also find some info on how to configure Rollup to output AMD modules. But what about input? What do I need to do when I have AMD modules as dependencies?
For example, suppose I have two different third party libraries that are both distributed as AMD libraries and I want to use those libraries in my Svelte project. How would I need to modify eg. this nested components demo to allow these AMD modules to be used as dependencies in my Svelte components?
Also, am I able to configure whether I bundle these libraries together with my Svelte components? If so, where would I need to do that?
Note
I also raised this issue on Github.
AMD modules are a pain to convert to ES modules, so you may find it difficult to bundle them with Rollup. (There's rollup-plugin-amd but it comes with caveats.)
But you can easily treat them as external dependencies that get loaded separately — just import them as normal then configure Rollup:
// rollup.config.js
export default {
// ...
format: 'amd',
external: ['an-external-amd-module'],
paths: {
'an-external-amd-module': 'https://my-cdn.com/an-external-amd-module.js'
}
};
You can see a demo here (repo here) — note that we're loading an exernal AMD module called the-answer, even though it's a regular import, because of the Rollup config.
I using requirejs to manage the javascript files in my project. However, there are some external libraries I want to use that do not adhere to the AMD format. A library I want to include is barba.js. How would this be done using the package loading feature of requirejs? Ideally I want to include a commonjs module without running a conversion tool.
Barba doesn't use the CommonJS module format.
Barba uses the UMD (Universal Module Definition) module format. This means that it is compatible with both the AMD module loading (as used by RequireJS) and CommonJS module loading (as used by Node.js).
So, that means you can just include Barba - or any other module in UMD format - with RequireJS the same way you include an AMD module:
define([
"barba/barba"
], function(Barba) {
Barba.Pjax.start(); // You can use Barba here
});
From requireJS doc.
define(function(require, exports, module) {
//Put traditional CommonJS module content here
});
This should make everything alright for you. I'm really not sure if it's needed though.
I'm using Webpack 1 for a frontend project and I have a legacy internal Javascript library which uses its own module system similar to AMD. A module is defined with a code similar to this:
MyLib.define('module id', ['my', 'module', 'deps'], function (my, module, deps) { /* module code */});
Then you can use the modules with a code like this:
MyLib.require(['dep1', 'dep2'], function (dep1, dep2) {});
I would like to be able to use MyLib along with all the other CommonJS modules I'm already using. Can webpack support this somehow?
As far as I know, Webpack doesn't support custom module formats (if someone else knows otherwise, I'd love to be proven wrong, though).
You perhaps could work around this by writing a Webpack loader or a Babel plugin that converts the syntax to one of the module formats that Webpack supports. The latter is what Babel used to do for ES6 imports before Webpack supported them out of the box - it'd just transform them into CommonJS require calls.
For example, can we write using AMD?
define([
'hb!./some/file.hb'
], function(template) {
//
})
To some extent, yes.
Because TypeScript is just a superset of JavaScript, any valid JavaScript is also valid TypeScript.
In your example, the compiler would complain about define:
error TS2304: Cannot find name 'define'.
You need to tell the compiler that define exists before you use it:
declare var define;
define([
'hb!./some/file.hb'
], function(template) {
//
})
This will let the compiler know that define exists, but it does not provide the compiler with any additional information about it. So, another solution would be to add the proper type definition.
To consume amd modules, you will still need to include an amd module loader. That isn't something that is built into TypeScript. TypeScript is just a super set of JavaScript.
Using TypeScript enables compiler type checking, and allows you to use newer JavaScript features, while compiling to older versions of JavaScript. However, TypeScript won't be able to understand what it is that another module exports, therefore you will need a declaration for each AMD module describing what the module exports.
To that end, as another answer points out, you can also write modules using the ES6 syntax, and compile them to the amd format. From the documentation at TypeScriptLang.org:
Depending on the module target specified during compilation, the compiler will generate appropriate code for Node.js (CommonJS), require.js (AMD), isomorphic (UMD), SystemJS, or ECMAScript 2015 native modules (ES6) module-loading systems. For more information on what the define, require and register calls in the generated code do, consult the documentation for each module loader.
Working on a set of scripts that will run in a browser context where certain modules (e.g. underscore) will be available as global modules. However, I'm depending on modules in node_modules that require / import underscore directly. Is it possible to configure WebPack to depend on the global underscore instance when compiling these files instead of duplicating that library in my compiled scripts?
What you're looking for are Externals:
externals configuration in webpack provides a way of not including a dependency in the bundle. Instead the created bundle relies on that dependency to be present in the consumers environment. This typically applies to library developers though application developers can make good use of this feature too.
This even works for modules in node_modules, as webpack walks the entire dependency tree to figure out what to include in the resulting bundle.
There's even an example that's specifically for your use case, it looks like:
externals : {
lodash : {
commonjs: "lodash",
amd: "lodash",
root: "_" // indicates global variable
}
}
This syntax is used to describe all the possible ways that an external library can be available. lodash here is available as lodash under AMD and CommonJS module systems but available as _ in a global variable form.
If you want to rely on a library already being available in the environment when your bundle is loaded, you need to make use of externals.
module.exports = {
externals: {
underscore: "_"
}
}
The key of the object (underscore) is what you use to import it, and the value (_) is the global variable it will look for.
require("underscore"); // Will return the _ variable from the global environment!