How to bundle legacy js files with webpack? - javascript

Suppose I have two files
a.js:
alert("hello from a.js");
b.js
alert("hello from b.js");
is there any way to bundle them with WebPack so that
I get both alerts synchronously as soon as bundle is loaded
alerts should be in the same order as declared
"hello from a" and then "hello from b"

Webpack natively supports CommonJS ( require / import ) and AMD style, and since yours are not falling into those categories, I believe you should look at the shimming modules section
https://github.com/webpack/docs/wiki/shimming-modules
This is from their header
In some cases webpack cannot parse some file, because it has a
unsupported module format or isn't even in a module format. Therefore
you have many options to convert the file into a module.

For anyone else that comes looking, the new (webpack 4+) link to the docs on shimming is here: https://webpack.js.org/guides/shimming/

For me personally, this webpack plugin was most helpful and headache free: https://www.npmjs.com/package/webpack-merge-and-include-globally

Related

Why do some minified js files contain calls to "require" function

I've been modernizing some old gulp config where js files are concatenated and then minified by migrating to webpack.
Some of bundles contained libraries such as moment.js and isotope-docs.min.js,
When bundling with webpack I would get error that specific file or path is not found.
For example looking at moment.js
There is require("./locale/"+t) which causes my webpack to fail since i dont have locale directory.
Why would bundled js file have require function when browsers dont understand that?
Before ES modules became a thing, JavaScript did not have an official module syntax. Also, developers wanted to write a library once for both Node.js and the browser. The closest thing available was Node.js's require(), which does not exist on the browser.
So what tools like Browserify and Rollup would do is polyfill an implementation of require() (e.g. wrap the code in a "UMD"). This way, the module worked on any plaform and require() calls work as if in Node.js (its implementation may vary and can be extended because dealing with the filesystem is very different from dealing with a network).
Found a fix, you can just add to webpack confing under module noParse e.g
webpack.config.js
module: {
rules: [ ... ]
noParse: /moment.min.js|isotope-docs.min.js/
}

Is there a way to bundle native ECMAScript modules?

I wonder if there a standard way to bundle native ES modules.
Suppose I have such a "brilliant" project (just for example):
<!-- index.html -->
<script type="module" src="./main.js"></script>
// main.js
import value from "./lib.js"
console.log(value);
// lib.js
export default 'hello world';
Now it needs three requests to load — it's too much, I need only two — .html and .js.
It looks simple at first glance (cat *.js > bundle.js) but there is no syntax for multiple ES modules in one file (as I can see).
I know I can translate ES modules syntax to some other module system (e. g. AMD) and then bundle them but it isn't what I want.
I am curious to accomplish this by native module features only. As simple and handmade as possible.
Is there a way to do this? Maybe at least a proposal?
Thank you.
rollup supports ESM as an output format as well. Your example transpiles to a simple script, but if you have exports in your entry module it will keep them.
rollup, webpack etc natively understand and can bundle ES modules.

import requirejs amd module with webpack

I'm using Converse.js and it's prebuilt into the RequireJS/AMD syntax. Including the file from a CDN you could use it like require(['converse'], function (converse) { /* .. */ }). How is it possible to use this with webpack? I would like to bundle converse.js with my webpack output.
I have the file on disk, and want to import it like
import converse from './converse.js';
converse.initialize({ .. });
Webpack picks up the file and bundles it correctly, although it's not useable yet as it throws 'initialize is not a function'. What am I missing?
I suspect the way their bundle is built will not work correctly with how Webpack evaluates modules in a limited context.
From their builds, taking the built AMD module via NPM without dependencies should be parsable by Webpack and it will enable you to provide the dependencies to avoid dupes in the final output.
If all else fails, using the script-loader will evaluate the script in the global context and you'd get the same experience as if you'd have followed their usage guidelines to reference it from a CDN, just don't forget to configure the globals for your linter.

Require third party RequireJS modules with Webpack

I'm working on an application that needs to pull in the ReadiumJS library, which uses AMD modules. The app itself is written in es6 w/ webpack and babel. I've gotten the vendor bundle working correctly, and it's pulling in the built Readium file, but when I try to require any of the modules Webpack says it can't resolve them. Anyone ever do this before with Webpack and RequireJS? Here's some info that may help - not sure what else to include as this is my first time really using Webpack..
Folder Structure
/readium-src
/readium-js
/ *** all readium-specific files and build output (have to pull down repo and build locally)
/node_modules
/src
/app.js -> main entry for my app
/webpack.config.babel.js
webpack.config.js entries
entry: {
vendorJs: [
'jquery',
'angular',
'../readium-src/readium-js/build-output/_single-bundle/readium-js_all.js',
'bootstrap/js/alert.js' //bootstrap js example
],
appJs: './app.js'
}
Trying to require it in app.js
var readiumSharedGlobals = require('readium_shared_js/globals');
I never really got into using RequireJS, so really struggling to understand how to consume that type of module along side other types of modules with webpack. Any help greatly appreciated :)
Update
If I change my app.js to use this instead:
window.rqReadium = require('../readium-src/readium-js/build-output/_single-bundle/readium-js_all.js');
Then it appears to try to load all the modules, but I get a strange error:
Uncaught Error: No IPv6
At this point, I'm unsure of
Should I have to require the entire path like that?
Is this error something from webpack, requirejs, or Readium? Tried debugging, but couldn't find anything useful...
UPDATE 8/12/2016
I think this is related to an issue with a library that Readium is depending on: https://github.com/medialize/URI.js/issues/118
However, I'm still not clear on how to correctly import AMD modules with webpack. Here's what I mean:
Let's say I have an amd module defined in moneyService.amd.js like this:
define('myMoneyService', ['jquery'], function($) {
//contrived simple example...
return function getDollaz() { console.log('$$$'); }
});
Then, in a sibling file, app.js, I want to pull in that file.
//this works
var getDollaz = require('./moneyService.amd.js');
//this works
require(['./moneyService.amd.js'], function(getDollaz) { getDollaz(); }
//this does not
require(['myMoneyService' /*require by its ID vs file name*/], function(getDollaz) {
getDollaz();
}
So, if we cannot require named modules, how would we work with a third party lib's dist file that has all the modules bundled into a single file?
Ok, so there's a repo out there for an Electron ePub reader using Readium, and it's using webpack: https://github.com/clebeaupin/readium-electron This shows a great way to handle pulling in RequireJS modules with webpack.
One super awesome thing I found is that you can specify output.library and output.libraryTarget and webpack will transpose from one module format to another... freaking awesome! So, I can import the requirejs module, set output library and libraryTarget to 'readium-js' and 'commonjs2' respectively, then inside my application code I can do import Readium from 'readium-js';

What is the main difference between bundle and bundleSFX in jspm?

I have tried harder and harder to understand the difference between bundle and bundle SFX from the documentation of JSPM and system.js. But I was unable to get the difference. I haven't used jspm till now but I want to use it in my current project.
Another question - If I am importing different modules in a.js and different modules in b.js, where both a.js and b.js are mutually exclusive, can I bundle both of them in a single file c.js using JSPM?
Please help, I would really appreciate it.
To create an output distributable script file that can be included
entirely on its own independent of SystemJS and jspm, we can use
bundle-sfx.
jspm bundle-sfx app/main.js app.js app.js
contains a micro-loader
implementation (1.4KB gzipped), converts all module formats into ES5
(including compiling ES6), and maintaining bindings and circular
references as with normal bundles.
Source: http://jspm.io/docs/production-workflows.html

Categories

Resources