RequireJS shim config in webpack - requirejs

I want to port my requirejs web application to webpack module bundler. The app use several non AMD libraries (such jquery and bootstrap). RequireJS maintains such libraries via shim configuration. How I can declare dependincies for non AMD libraries in webpack?

I'm in the process of doing the same. It's practically as you would any AMD module. To use stringified templates put into AngularJS' $templateCache as an example:
Templates are generated in non-AMD format wrapped in an IIFE, pushed into a .tmp dir, then requested as per any module:
define([
'./module',
'templates/ubCampaignEditor'
]
As to keep definitions clean, I've created a resolve.alias named templates, in the Webpack config:
resolve: {
alias: {
templates: path.join(__dirname, '.tmp/templates')
}
}

Related

Webpack fails with Node FFI and Typescript - dynamic require error

In a simple Typescript program I require Node FFI with
import * as Electron from 'electron';`
import * as ffi from 'ffi';`
and then
mylib = ffi.Library('libmoi', {
'worker': [ 'string', [ 'string' ] ],
'test' : [ 'string', [] ]
} );
Linking that up via webpack yields
WARNING in ./~/bindings/bindings.js
Critical dependencies:
76:22-40 the request of a dependency is an expression
76:43-53 the request of a dependency is an expression
# ./~/bindings/bindings.js 76:22-40 76:43-53
The problem seems to be that FFI has a dynamic require and the fix seems to be to apply webpack.ContextReplacementPlugin in the webpack.config.js file.
This is a bit out of my reach, but an example for an Angular case is:
plugins: [
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
root('./src') // location of your src
)
]
Any idea how to do this for FFI?
Here is the answer: github issue comment on the Johnny-Five repo
Quoting from brodo's answer, this is what you do to stop webpack getting snarled up with "bindings" and similar:
... the webpack config looks like this:
module.exports = {
plugins: [
new webpack.ContextReplacementPlugin(/bindings$/, /^$/)
],
externals: ["bindings"]
}
I also had a similar issue, somehow, I managed to resolve it. I will first explain my understanding.
Main work of webpack is to bundle the separate code file into one file, by default it bundles all the code that is referenced in its tree.
Generally two types of node_modules:
To be used on browser side(angular, rxjs etc)
To be used on nodejs side(express, ffi etc)
It is safer to bundle browser side node_module but not safer to bundle node side node_module because they are not designed like that So the solution is below two steps:
Give appropriate target(node, electron etc) in webpack.config.js file e.g "target":'electron-renderer' by default it is browser
Declare node_side module as external dependency in your webpack.config.js file e.g.
"externals": {
"bindings": "require('bindings')",
"ffi": "require('ffi')"
}

How to replace requireJS config in webpack es6 project

I want to refactor a large requireJS project to use es6 import/export and webpack. In the requireJS requirejs.config call, I use the config section to pass some project specific settings to some views:
requirejs.config({
baseUrl: 'js/cfe/app',
paths: { },
config: {
'views/test/TestView': {
isTest: true
}
})
and in the view:
define(['module'], function(module) {
var t = module.config().isTest
})
How can I accomplish the same behaviour in my webpack setup?
I'm not quite sure if I understand your question correctly, but maybe you can use my answer anyways.
I think you could extract your configuration object to JSON file, use a loader (RAW loader works fine) to include it in your bundle, and then when you need it simply use ES6 import:
import config from 'myconfig.json';

TinyMCE 4.2.5 not compatible with RequireJS

I'm having problems setting up TinyMCE with an existing setup of RequireJS. The bootstrap file (tinymce.dev.js, tinymce.js, tinymce.jquery.js, tinymce.jquery.dev.js) for TinyMCE 4.2.5 has its own define and require functions, which overwrite the ones supplied by RequireJS. I've tried commenting out the lines so that they don't overwrite the existing RequireJS functions, but this doesn't help.
I'm also using tinymce in my project. You don't have to modify any of the script file. To make it work you have to shim the tinymce library hence it will be fully compatible with requirejs (http://requirejs.org/docs/api.html#config-shim).
So in your requirejs config you should have something like that :
requirejs.config({
...
baseUrl : 'your_lib_path',
shim : {
...
'tinyMCE': { exports: 'tinyMCE'}
},
paths: {
...
'tinyMCE': 'tinymce/tinymce' //path from the baseUrl to tinymce.js ("js" extension has to be ommited)
}
});

requirejs HTML structure

I know we could use requirejs combine files into one js file.
such like the following config.
module.exports = {
baseUrl: 'js/',
mainConfigFile: 'src/js/common.js',
dir: 'scripts/',
optimize: 'uglify2',
modules: [
{
name: 'common',
include: [
'jquery',
]
}
]
};
my result into one file is
common.js
----------------
jquery.js
modernizr.js
common.js
my question is, do we still need to put a require.js file in scripts folder and to use the following format
<script data-main="scripts/common" src="scripts/require.js"></script>
or we could just use
<script src="scripts/common.js"></script>
as files are compressed into one file?
You still need to load require.js the usual way to actually make use of the module loading benefits that it provides, and especially if you use the asynchronous functionality a lot. However, you can have a look at almond providing your code uses AMD and (from the README):
optimize all the modules into one file -- no dynamic code loading.
all modules have IDs and dependency arrays in their define() calls -- the RequireJS optimizer will take care of this for you.
only have one requirejs.config() or require.config() call.
do not use RequireJS multiversion support/contexts.
do not use require.toUrl() or require.nameToUrl().
do not use packages/packagePaths config. If you need to
use packages that have a main property,
volo can create an adapter module so
that it can work without this config. Use the amdify add command to
add the dependency to your project.
Almond is great because it doesn't need require.js at all; it wraps your own code with itself, which is a very minimal AMD loader skeleton and nowhere near as powerful as the main library. You then get a single optimised file that can be linked directly in your HTML:
<script src="scripts/common.js"></script>
The Gruntfile config for almond could look something like this:
compile: {
options: {
name: 'path/to/almond',
baseUrl: 'js',
include: ['main'],
insertRequire: ['main'],
mainConfigFile: 'scripts/config.js',
out: 'scripts/main.js',
optimizeAllPluginResources: true,
wrap: true
}
}
The above is all standard r.js boilerplate, you can find many more examples at the almond homepage.

dose requirejs need all JS files to support AMD

i'm reading little about requireJS and trying to understand it.
What i want to know:
Should i structure my files in specific way or pattern like Module-Pattern ??
When working with libraries should these files support AMD ?
Thanks Alot for your help.
You can structure your files any way you see fit. RequireJS loads the script file referenced in the data-main attribute of the script tag that loads require.js. From that file you're free to require whatever modules you want.
Libraries don't need to support AMD. You can use the shim config to load modules that export value to the global scope (i.e. normal javascript files).
Mostly I'm setting up a require.js project with a structure as below:
root
js
modulesType1
mod1
mod2
modulesType2
mod1
mod2
app.js
bootstrap.js
lib
require
require.js
lib1
lib1.js
css/img/partials/...
index.html
And an initial bootstrap.js a have a require.config object and an initial require:
/*global define, require */
require.config({
baseUrl: 'js',
paths: {
lib1: '../lib/lib1/lib1'
},
shim: {
lib1: ['something']
}
});
require(['lib1', 'app'], function (lib1, app) {
app.doSth();
});
In your html page you only need one script tag with a data-main attribute:
<body>
...
<script type="text/javascript" src="lib/require/require.js" data-main="js/bootstrap"></script>
</body>
Edit: modules don't have to be AMD compliant, but if they are under your own control, it is better to make them AMD compliant. You can make third party non-AMD libraries loadable using the shim property in require.config.

Resources