How to build requirejs app with webpack? - javascript

I have a requirejs app which gets loaded from the require config pasted below. The path references to the vendor directory are 3rd party libraries loaded via bower.
// Require.js Configurations
// -------------------------
require.config({
baseUrl: './js/app',
paths: {
'backbone' : '../../vendor/backbone/backbone',
'backbone.paginator' : '../../vendor/backbone.paginator/lib/backbone.paginator',
'backbone.validateAll': '../../vendor/Backbone.validateAll/src/javascripts/Backbone.validateAll.js',
'backbone.wreqr' : '../../vendor/backbone.wreqr/lib/backbone.wreqr.js',
'handlebars' : '../../vendor/handlebars/handlebars.runtime',
'handlebars-helpers' : '../../vendor/handlebars-helpers/src/helpers',
'jasminejquery' : '../../vendor/jasmine-jquery/lib/jasmine-jquery',
'jquery' : '../../vendor/jquery/dist/jquery',
'jquerymobile' : '../../vendor/jquery-mobile-bower/js/jquery.mobile-1.4.5',
'loglevel' : '../../vendor/loglevel/lib/loglevel',
'marionette' : '../../vendor/marionette/lib/backbone.marionette',
'modernizr' : '../../vendor/modernizr/modernizr',
'moment' : '../../vendor/moment/moment',
'swiper' : '../../vendor/swiper/dist/idangerous.swiper',
'templates/jst' : '../../build/tmp/templates/jst-build',
'underscore' : '../../vendor/lodash/dist/lodash'
},
shim: {
'backbone.validateAll' : ['backbone'],
'jasminejquery' : ['jquery'],
'jquerymobile' : ['jquery'],
'modernizr' : { exports: 'Modernizr' },
'swiper' : ['jquery']
}
});
// Bootstraps
require(['bootstrap/backbone'], function(){});
require(['bootstrap/jquery'], function(){});
// App
require(['init/Main'], function(main) {});
The issue I'm getting in my console says that my bootstrap files are not found which only leads me to believe that webpack is not loading in my require.config.
$ webpack ./app/config/requirejs.js ../build/test.js Hash: f33deaf4b2ff288e08b6 Version: webpack 1.5.3 Time: 61ms Asset Size
Chunks Chunk Names test.js 2435 0 [emitted] main
[0] ./app/config/requirejs.js 1691 {0} [built] [3 errors]
ERROR in ./app/config/requirejs.js Module not found: Error: Cannot
resolve module 'bootstrap/backbone' in
/Users/glitches/Sites/public/js/app/config #
./app/config/requirejs.js 35:0-45
ERROR in ./app/config/requirejs.js Module not found: Error: Cannot
resolve module 'bootstrap/jquery' in
/Users/glitches/Sites/public/js/app/config #
./app/config/requirejs.js 36:0-43
ERROR in ./app/config/requirejs.js Module not found: Error: Cannot
resolve module 'init/Main' in
/Users/glitches/Sites/public/js/app/config #
./app/config/requirejs.js 39:0-41
I'm guessing I need to rewrite my requirejs configuration as an entry point but I'm asking here incase anyone has a better idea of how to go about this.

Your require statements are trying to resolve as modules in your node_modules folder, because there is no absolute or relative path.
How modules are resolved, depending on path type.
If you are requiring files within your application's source, use a relative or absolute path.
// Bootstraps
require(['../bootstrap/backbone'], function(){});
require(['../bootstrap/jquery'], function(){});
// App
require(['../init/Main'], function(main) {});
This assumes a structure where this is at /app/config/requirejs.js and your target modules are at /app/bootstrap/backbone.js, /app/bootstrap/jquery.js, and /app/init/Main.js.

Related

Include file with module from AngularJS app into RequireJS config file in Karma

As we know, when use RequireJS in the configuration file we must define 'paths' and 'shim'. When writing tests (Karma, Jasmine), we need to create an additional configuration file for RequireJS and re-define the same data.
I try to extract common parts and load them dynamically. In Angular JS application, everything works without problems, but in test i have always error '404'. But let's get to the beginning. Simple example structure:
.
|-- newApp
| |-- app
| | `-- app.require.js
| |-- newApp.require.js
| `-- index.html
`-- test
|-- test.karma.js
`-- test.require.js
index.html load RequireJS config file
<script data-main="newApp.require.js" src="bower_components/requirejs/require.js"></script>
newApp.require.js init RequireJS
require([
'app/app.require'
], function (appRequire) {
"use strict";
require.config({
baseUrl: 'app',
paths: appRequire.paths,
shim: appRequire.shim,
deps: [
'NewAppBootstrap'
]
});
});
app.require.js Module / object with paths and shim
define([
'some/others/components.require'
], function (componentsRequire) {
"use strict";
var appRequire = {
'NewApp': 'app.module',
'NewAppBootstrap': 'app.bootstrap',
'NewAppRoute': 'app.routes'
};
var vendorRequire = {
'jQuery': {
exports: '$'
},
'angular': {
exports: 'angular'
}
};
return {
paths: Object.assign(
appRequire,
componentsRequire
),
shim: vendorRequire
};
});
Up to this point everything works fine. Now I would like to file app.require.js load into test.require.js. And the problems begin...
test.require.js
var TEST_REGEXP = /(spec|test)\.js$/i;
var allTestFiles = [];
Object.keys(window.__karma__.files).forEach(function (file) {
'use strict';
if (TEST_REGEXP.test(file)) {
var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '');
allTestFiles.push(normalizedTestModule);
}
});
require([
'app/app.require'
], function (appRequire) {
"use strict";
require.config({
baseUrl: '/base/newApp',
waitSeconds: 200,
paths: appRequire.paths,
shim: appRequire.shim,
deps: allTestFiles,
callback: window.__karma__.start
});
});
Unfortunately, I still have error:
WARN [web-server]: 404: /app/app.require.js
PhantomJS 2.1.1 (Linux 0.0.0) ERROR: 'There is no timestamp for app/app.require.js!'
PhantomJS 2.1.1 (Linux 0.0.0) ERROR
Error: Script error for "app/app.require"
http://requirejs.org/docs/errors.html#scripterror at node_modules/requirejs/require.js:143
I tried different paths, but still nothing. Does anyone know how to load this file? Whether it is at all possible load file in this place? I would be grateful for any tips.
By the time your code hits this require call:
require([
'app/app.require'
],
There is no RequireJS configuration in effect, and data-main is not used, so by default RequireJS takes the directory that contains the HTML page that loads RequireJS as the baseUrl (See the documentation.) Since index.html sits at the root, then RequireJS resolves your module name to /app/app.require.js and does not find it.
You can work around it by using a full path:
require([
'base/newApp/app/app.require'
],
Or if it so happens that other code later is going to try to access this same module as app/app.require, then you should have a minimal configuration before your first require call:
require.config({
baseUrl: '/base/newApp',
});
It is perfectly fine to call require.config multiple times. Subsequent calls will override values that are atomic (like baseUrl) and marge values that can be merged. (An example of the latter would be paths. If the first call sets a paths for the module foo and a 2nd call sets a paths for the module bar, then the resulting configuration will have paths for both foo and bar.)

Webpack Error - Cannot Resolve File or Directory

I am getting this error when I npm start my webpack-dev-server:
ERROR in multi main
Module not found: Error: Cannot resolve 'file' or 'directory' /var/www/html/151208-DressingAphrodite/app in /var/www/html/151208-DressingAphrodite
# multi main
Here is my webpack.config.js:
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require ('html-webpack-plugin');
const PATHS = {
app: path.join (__dirname, 'app'),
build : path.join (__dirname, 'build')
};
module.exports = {
entry : [
'babel-polyfill',
'webpack-dev-server/client?http://localhost:8080',
PATHS.app
],
output : {
publicPath : '/',
filename : 'dressingaphrodite.js',
hash : true
},
debug : true,
devServer : {
contentBase : './app'
},
devtool : 'source-map',
module : {
loaders : [
{
test : /\.jsx?$/,
include : PATHS.app,
loader : 'babel-loader',
query : {
presets : ["es2015"]
}
},
{
test: /\.css$/,
include: PATHS.app,
loader: 'style!css'
}
]
},
plugins : [
new HtmlWebpackPlugin ({
title : 'Dressing Aphrodite',
filename : 'da.html'
})
]
};
ok if any one face this problem, you can solve it in 2 methods:
Method 1:
1- add a file called package.json inside your entry folder (in your case put it inside the folder "{project_dir}/app/package.json")
2- inside this file write any json object for example:
{
"name": "webpack why you do diss :("
}
Method 2:
Change your entry files to be at least 2 level away from your project home directory, for example: "{project_dir}/src/app"
Explanation: for each entry file webpack will try to find a file called package.json to use it for webpack configuration incase this entry file is a module, when you put your entry file only 1 level away from your project home dir webpack will use your project packge.json as configuration file for your entry file and it will fail because of miss configuration.
You should check the browser console. It provides more detailed informations.
In my case:
Uncaught Error: Cannot find module "./src/index"
at webpackMissingModule (webpack:///multi_main?:4)
at eval (webpack:///multi_main?:4)
at Object.<anonymous> (bundle.js:586)
at __webpack_require__ (bundle.js:556)
at bundle.js:579
at bundle.js:582
So here is the error a missing (or misspelled) java script file.
The same problem I met. I found an answer in github Error : ERROR in Entry module not found: Error: Cannot resolve 'file' or 'directory'#981. But sadly, in webpack 1.15.12, the --allow-incompatible-update has been remove. Also, I found when set the entry type is array, such as entry: [entry.js], webpack will run, but throw another error:(
I wish it can help you, hopefully.

Compiled requirejs modules require calls are executing before modules are defined resulting in 'Undefined is not a function'

I've compiled my requirejs file using r.js and occasionally on page load, modules aren't defined as (I'm assuming) that require and define calls are running asynchronously and modules aren't getting defined by the time the require call has executed.
I'm pretty sure my shim is correct, my waitSeconds is set to 0 (infinite) and all my exports are set up.
Here's my (shortened) requirejs file:
requirejs.config({
defaultPath: 'javascript',
waitSeconds: 0,
// paths to plugins
paths : {
'jquery' : 'plugins/jquery-1.9.1.min',
'owl' : 'plugins/owl.carousel.min'
},
// dependency order if applicable
shim : {
'jquery' : {
exports: '$'
},
'owl' : {
deps: ['jquery'],
exports: 'owlCarousel'
}
}
});
require(['jquery','owl'], function($, owlCarousel){
$('.carousel').owlCarousel();
});

Avoid duplication of "paths" configuration in RequireJS main file and r.js build file?

Here is (part of) my folder structure:
node-test
bower_components
build
public
main.js
build.js
Running the optimizer with r.js -o build.js and the following configuration works fine:
// main.js file
requirejs.config({
baseUrl: '../bower_components',
paths: {
'domready': 'domready/ready',
'jquery': 'jquery/jquery',
}
});
requirejs(['domready', 'jquery'], function (domReady, $) {
domReady(function () {
});
});
// build.js file
({
baseUrl: "bower_components",
name: "./almond/almond",
include: "./../public/main",
out: "build/main.js",
paths: {
'domready': 'domready/ready',
'jquery': 'jquery/jquery',
},
preserveLicenseComments: false
})
However, if I remove paths configuration in build.js it doesn't work anymore:
Tracing dependencies for: ./almond/almond Error: ENOENT, no such file
or directory
'C:\Users\Marco\Documents\Progetti\nodejs-opt\bower_components\domready.js'
In module tree:
../public/main
Error: Error: ENOENT, no such file or directory
'C:\Users\Marco\Documents\Progetti\nodejs-opt\bower_components\domready.js'
In module tree:
../public/main
at Object.fs.openSync (fs.js:427:18)
I'd like to be DRY, avoiding adding a dependency twice. Is this possible?
If you want to use same configuration from your runtime code to find the location of your libraries, you can use the mainConfigFile option:
...if you prefer the "main" JS file configuration to be read for the build so that you do not have to duplicate the values in a separate configuration, set this property to the location of that main JS file. The first requirejs({}), require({}), requirejs.config({}), or require.config({}) call found in that file will be used.
Something like this:
({
baseUrl: "bower_components",
mainConfigFile: '/some/path/main.js', // adjust path as needed
name: "./almond/almond",
include: "./../public/main",
out: "build/main.js",
preserveLicenseComments: false
})

RequireJS Setting Path to the Parent Level

In order to direct my models, collections, etc. from my mobile app to my web app, I need to configure my RequireJS.
I have the following file structure:
/
/js
/models
/mobile
/js
/templates
I want my mobile app to use my main app's models, so I set the following:
require.config( {
paths : {
models : '/js/models',
templates : 'mobile/templates'
}
});
And I get these errors in Chrome:
Uncaught SyntaxError: Unexpected token < /mobile/js/models/User.js?bust=0.1.0:1
Uncaught SyntaxError: Unexpected token < /mobile/js/models/InviteRequest.js?bust=0.1.0:1
Uncaught SyntaxError: Unexpected token < /mobile/js/models/Log.js?bust=0.1.0:1
Meaning that it's still looking in /mobile instead of /.
This path config works for my templates folder, but not my models folder. How can I point all require dependencies that start with models/ to my main models folder?
Thanks!
ATTEMPT 2
I tried setting the baseUrl instead:
require.config( {
baseUrl : '/',
paths : {
views : 'mobile/views',
templates : 'mobile/templates'
}
});
require( [
'app'
],
function(App) {
App.initialize();
});
I get the error:
GET http://local.m.mysite.co/app.js 404 (Not Found) require.js:2
In your second attempt, you basically tell Require JS to load 'app' module and since you set the base url to '/', Require JS will look 'app' module in your root path.
So what you need to do is to tell Require JS where to look for your 'app' module. Say your 'app' module is in /js/module:
/
/js
/models
/module
/app.js
/mobile
/js
/templates
Then your code to load 'app' module is:
require.config( {
baseUrl : '/',
paths : {
views : 'mobile/views',
templates : 'mobile/templates'
}
});
require( [
'js/module/app'
],
function(app) {
app.initialize();
});
Alternatively, you can set 'module' path in your config. Then refer to this path in your dependency loading:
require.config( {
baseUrl : '/',
paths : {
views : 'mobile/views',
templates : 'mobile/templates',
module: 'js/module'
}
});
require( [
'module/app'
],
function(app) {
app.initialize();
});
As for the error you get in Chrome before your ATTEMPT 2, you will need to look at how you refer to your module in module loading.

Categories

Resources