How to replace requireJS config in webpack es6 project - requirejs

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';

Related

How can I make webpack skip a require

How can I make webpack skip occurences of
require('shelljs/global');
in my source files? I want to make a bundle of my source files but keep the require('shelljs/global') in the files and not bundle shelljs/global.
If you store the path in a variable then IgnorePlugin will not work. Though you still could do:
const myCustomModule = eval('require')(myCustomPath)
for new comers, on webpack 2+ the way to do this is like so:
module.exports = {
entry: __dirname + '/src/app',
output: {
path: __dirname + '/dist',
libraryTarget: 'umd'
},
externals: {
'shelljs/globals': 'commonjs shelljs/global'
}
};
the bundle will contain a verbatim require:
require('shelljs/global');
read on more supported formats on webpack's config guide and some good examples here
You can use Ignore Plugin (webpack 1) / Ignore plugin (webpack 2).
Add plugin in webpack.config.js:
plugins: [
new webpack.IgnorePlugin(/shelljs\/global/),
],
If require is in the global namespace and this is why you want Webpack to ignore it, just do window.require()
This should be a last resort option, but if you are certain that your JS file is always parsed by Webpack, and nothing else:
You could replace your require() calls with __non_webpack_require__()
Webpack will parse and convert any occurrence of this and output a normal require() call. This will only work if you are executing in NodeJS OR in a browser if you have a global require library available to trigger.
If webpack does not parse the file, and the script is run by something else, then your code will try to call the non-converted __non_webpack_require__ which will fail. You could potentially write some code that checks earlier in your script if __non_webpack_require__ exists as a function and if not, have it pass the call on to require.
However, this should be temporary, and only to just avoid the build errors, until you can replace it with something like Webpack's own dynamic imports.
Here a trick
const require = module[`require`].bind(module);
Note the use of a template string
If some files contains nested requires and You want to ignore them, You can tell webpack to not do parsing for these specific files.
For example if swiper.js and vue-quill-editor.js had inner requires this would be how to ignore them.
module.exports = {
module: {
noParse: [
/swiper.js/,/quill/
],

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 shim config in webpack

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')
}
}

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.

Use RequireJS config file as the build file?

I've got some paths configured in require-config.js as follows:
var require = {
baseUrl: '/javascript',
paths: {
'jquery': 'jquery/jquery-1.8.1.min'
// etc. -- several paths to vendor files here
},
}
I am trying to get the optimization working for deployment. The docs say I should have a build.js that looks something like this:
({
baseUrl: 'javascript',
paths: {
'jquery': 'jquery/jquery-1.8.1.min'
},
name: 'main',
out: 'main-build.js'
})
Is there a way to have the optimizer read my config file instead of (or in addition to) build.js? I don't want to have to manually keep the paths configured the same in both files if they change.
I tried to just run node r.js -o path/to/require-config.js, but it threw an error, "malformed: SyntaxError: Unexpected token var"
Edit: for clarification, my require-config.js file is the config only, not my main module. I did this so I could use the same configuration but load a different main module when unit testing.
You'll need to adjust the way your config options are defined. Taken from the RequireJS documentation:
In version 1.0.5+ of the optimizer, the mainConfigFile option can be used to specify the location of the runtime config. If specified with the path to your main JS file, the first requirejs({}), requirejs.config({}), require({}), or require.config({}) found in that file will be parsed out and used as part of the configuration options passed to the optimizer:
So basically you can point your r.js build file to your config options that will also be shared with the browser.
You will need to make use of the mainConfigFile option
For other's reference:
https://github.com/jrburke/r.js/blob/master/build/example.build.js
The build settings (no need to repeat your config.js lib inclusions here):
baseUrl: 'app',
name: 'assets/js/lib/almond', // or require
// Read config and then also build it into the app
mainConfigFile: 'app/config.js',
include: ['config'],
// Needed for almond (and does no harm for require)
wrap: true,

Resources