I am using requirejs and gulp to build angular app. I am using amd-optimize and gulp-requirejs-optimize to add all js files into single file. Here is my main.js file:
require.config(
{
paths: {
app : 'app',
angular : '../bower_components/angular/angular',
jquery : '../bower_components/jquery/dist/jquery',
angularResource : '../bower_components/angular-resource/angular-resource',
angularRoute : '../bower_components/angular-route/angular-route',
publicModule : 'public_module',
route : 'route'
},
shim: {
'app': {
deps: ['angular']
},
'angularRoute': ['angular'],
angular : {exports : 'angular'}
}
}
);
And gulpfile.js
var gulp = require('gulp');
var rjs = require('gulp-requirejs');
var connect = require('gulp-connect');
var requirejsOptimize = require('gulp-requirejs-optimize');
var amdOptimize = require('amd-optimize');
var concat = require('gulp-concat');
// using amd-optimize.
gulp.task('bundle', function () {
return gulp.src('app/**/*.js')
.pipe(amdOptimize('main'))
.pipe(concat('main-bundle.js'))
.pipe(gulp.dest('dist'));
});
// using gulp-requirejs-optimize.
gulp.task('scripts', function () {
return gulp.src('app/main.js')
.pipe(requirejsOptimize())
.pipe(gulp.dest('dist'));
});
When I run gulp bundle or gulp scripts, it shows me same content of main.js file in output file(not showing all js template in one output file).
The output file is:
require.config({
paths: {
angular: '../bower_components/angular/angular',
jquery: '../bower_components/jquery/dist/jquery',
angularResource: '../bower_components/angular-resource/angular-resource',
angularRoute: '../bower_components/angular-route/angular-route',
publicModule: 'public_module',
route: 'route'
},
shim: {
'app': { deps: ['angular'] },
'angularRoute': ['angular'],
angular: { exports: 'angular' }
}
});
define('main', [], function () {
return;
});
How can I configure gulp to put every js template into one js file?
check the docs for all the options for amdoptimize. For example you can point to your config file or add paths.
I always have trouble getting all the paths to line up, so make sure to check them diligently.
here is how you can start to put the options in:
gulp.task('requirejsBuild', function() {
gulp.src('app/**/*.js',{ base: 'app' })
.pipe(amdOptimize("app",{
baseUrl: config.app,
configFile: 'app/app-config.js',
findNestedDependencies: true,
}))
.pipe(concat('app.js'))
.pipe(gulp.dest('dist'))
});
You are not requiring any files - you just define an empty module named main.
You need to kick off you app by requiring a module, eg.
require(['app'], function (App) {
new App().init();
});
Related
I am working on a small project that needs .sass files compiled into .css files. I have used Gulp a while ago and loved it, but my old gulpfile.js does not work anymore, because Gulp has changed since version 4.
I have made a new gulpfile.js:
var gulp = require('gulp'),
sass = require('gulp-sass'),
rename = require('gulp-rename');
var paths = {
styles: {
src: 'src/scss/*.scss',
dest: 'build/css'
}
};
function styles() {
return gulp
.src(paths.styles.src, {
sourcemaps: true
})
.pipe(sass())
.pipe(rename({
basename: 'main',
suffix: '.min'
}))
.pipe(gulp.dest(paths.styles.dest));
}
function watch() {
gulp
.watch(paths.styles.src, styles);
}
var syncConfig = {
server: {
baseDir : './',
index : 'index.html'
},
port : 3000,
open : false
};
// browser-sync
function server() {
init(syncConfig);
}
var build = gulp.parallel(styles, watch, server);
gulp
.task(build);
gulp
.task('default', build);
I have a "Did you forget to signal async completion?" error returned by the console.
Where is my mistake?
There ware two things missing: the browsersync variable browsersync = require('browser-sync').create() and the callback for the server function:
function server(done) {
if (browsersync) browsersync.init(syncConfig);
done();
}
It compiles SASS to CSS, still there is this problem: the page does not reload automatically when changes are made in the main.scss.
Here is the entire code:
var gulp = require('gulp'),
browsersync = require('browser-sync').create(),
sass = require('gulp-sass'),
rename = require('gulp-rename');
var paths = {
styles: {
src: 'src/scss/*.scss',
dest: 'build/css'
}
};
function styles() {
return gulp
.src(paths.styles.src, {
sourcemaps: true
})
.pipe(sass())
.pipe(rename({
basename: 'main',
suffix: '.min'
}))
.pipe(gulp.dest(paths.styles.dest));
}
function watch() {
gulp
.watch(paths.styles.src, styles);
}
var syncConfig = {
server: {
baseDir : './',
index : 'index.html'
},
port : 3000,
open : false
};
// browser-sync
function server(done) {
if (browsersync) browsersync.init(syncConfig);
done();
}
var build = gulp.parallel(styles, watch, server);
gulp
.task(build);
gulp
.task('default', build);
I currently have 2 separate webpack builds for server rendered vs client rendered code. Is there an easy way to change the build output based on server/client build?
For example something like this:
// Have some code like this
if(is_client){
console.log('x.y.z')
} else {
server.log('x.y.z')
}
// Webpack outputs:
// replaced code in client.js
console.log('x.y.z')
// replaced code in server.js
server.log('x.y.z')
Have you tried anything like this?
// webpack.config.js
module.exports = () => ['web', 'node'].map(target => {
const config = {
target,
context: path.resolve('__dirname', 'src'),
entry: {
[target]: ['./application.js'],
},
output: {
path: path.resolve(__dirname, 'dist', target),
filename: '[name].js'
},
modules: { rules: ... },
plugins: [
new webpack.DefinePlugin({
IS_NODE: JSON.stringify(target === 'node'),
IS_WEB: JSON.stringify(target === 'web'),
}),
],
};
return config;
});
// later in your code
import logger from 'logger';
if (IS_NODE) {
logger.log('this is node js');
}
if (IS_WEB) {
console.log('this is web');
}
how the compilation works?
// client.bundle.js
import logger from 'logger';
// DefinePlugin creates a constant expression which causes the code below to be unreachable
if (false) {
logger.log('this is node js');
}
if (true) {
console.log('this is web');
}
Finally you will produce your build in production mode, so webpack will include a plugin called UglifyJS, this has a feature called dead code removal (aka tree shaking), so it will delete any unused/unreachable code.
and the final result will look like:
// node.bundle.js
import logger from 'logger';
console.log('this is node js');
//web.bundle.js
console.log('this is node js');
On some occasions, requirejs returns an undefined object to my module. I've looked at a number of posts and most of the answer are related to circular dependencies. However I could find none (I have checked several times). I apologize by advance for pasting a quantity of code that I've tried to reduced to the minimum :) Any help would be greatly appreciated!
Here is the module init_app.js that fails:
define([
'marionette',
], function(
Marionette
) {
"use strict";
var App;
App = new Marionette.Application();
App.addRegions({ body: "#main_body" });
return App;
});
Sometimes the Marionette module is undefined. Here is the part of my config.js that might be relevant:
define([], function() {
'use strict';
require.config({
baseUrl: 'js',
paths : {
underscore : 'vendors/underscore/underscore',
jquery : 'vendors/jquery/dist/jquery',
backbone : 'vendors/backbone/backbone',
marionette : 'vendors/marionette/lib/backbone.marionette',
wreqr : 'vendors/backbone.wreqr/lib/backbone.wreqr',
eventbinder : 'vendors/backbone.eventbinder/lib/backbone.eventbinder',
babysitter : 'vendors/backbone.babysitter/lib/backbone.babysitter',
},
shim : {
jquery : {
exports : 'jQuery'
},
underscore : {
exports : '_'
},
backbone : {
deps : ['jquery', 'underscore'],
exports : 'Backbone'
},
wreqr: {
deps : ['backbone'],
exports: 'Backbone.Wreqr'
},
eventbinder : {
deps : ['backbone']
},
babysitter : {
deps: ['backbone']
},
marionette : {
deps: ['backbone', 'wreqr', 'eventbinder', 'babysitter'],
exports : 'Marionette'
},
}
});
});
The main.js file is
require(['config'], function() {
require( ['app'], function (App) {
App.start({});
});
});
where the app.js file is
define([
'init_app',
'router',
], function(
App,
Router
) {
"use strict";
App.on('start', function() {
new Router();
Backbone.history.start();
});
return App;
});
And the router will define a bunch of things that might depend on init_app.js. I've been especially carefull that none of them defines the app.js, which should be sufficient to guaranty that no circular dependency could cause this bug. Any clue??
You should review your shim configuration to remove all those shims that you've put in for modules that actually use define. For instance, jQuery uses define and thus does not need a shim. The same is true of Marionette. I've just installed it with Bower and found this towards the start of the file:
if (typeof define === 'function' && define.amd) {
define(['backbone', 'underscore'], function(Backbone, _) {
return (root.Marionette = root.Mn = factory(root, Backbone, _));
});
}
...
If you see something like this in a module you use, or a flat out call to define, then you should not use a shim for it.
I've not checked every single module you use. Please review all of them to make sure you do not use shims where not needed. If you use shims incorrectly, you can get undefined values for your modules.
Here is how I solved it: I changed the main.js to
require(['config'], function() {
require( ['init_app'], function () {
require( ['app'], function () {
App.start({});
});
});
});
and put the App in the global scope in init_app. This works well but doesn't explain the previous failure.
im struggling with a weird Issue with Backbone.Marionette an requireJS.
RquireJS is configured like https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs says:
require.config({
deps: ['main'],
paths : {
backbone : '../vendor/backbone.marionette/backbone',
underscore : '../vendor/underscore/underscore',
jquery : '../vendor/jquery/jquery',
marionette : '../vendor/backbone.marionette/backbone.marionette.min'
},
shim : {
jquery : {
exports : 'jQuery'
},
underscore : {
exports : '_'
},
backbone : {
deps : ['jquery', 'underscore'],
exports : 'Backbone'
},
marionette : {
deps : ['jquery', 'underscore', 'backbone'],
exports : 'Marionette'
}
}
});
The main.js:
require([
'app'
],
function(App) {
App.start();
}
);
And the app.js:
define([
'marionette'
],
function(Marionette) {
var app = Marionette.Application();
return app;
}
);
But when I wanna start a Application my Console says:
Uncaught TypeError: Object #<Object> has no method '_initRegionManager'
I did nothing special so far:
define(
[
'marionette'
],
function(Marionette) {
"use strict";
var app = Marionette.Application();
// app.on('initialize:after', function() {
// console.log("Initialize:After");
// });
return app;
}
);
And in the main.js (Startingpoint) i require the code above and wanna start it.
But it fails at Marionette.Application();
When i look into the marionette.js i can clearly see underscore extending the Application with the _initRegionManager-Method. Also in the Prototype-list of the Marionette-Object i can see the method.
Any ideas what i'm missing here?
Your require.config ({ … }) should be in main.js and also as Ratweb_on indicated, there should not be “deps: [‘main’]” in the require.config.
You can follow this example in here, and ignore the jquerymobile stuffs. Essentially it dose the initialization in the same way as your code intended.
See main.js and app.js.
Updated
In your app.js
var app = Marionette.Application();
Should be
var app = new Marionette.Application();
I've got the following requireJS config. When trying to reference the package/ImagingX module I always get undefined even though I can see that the script has been loaded in firebug. If I move the js file in question into the baseUrl directory and remove package/ it works as expected.
What am I doing wrong?
window.requirejs.config(
{
baseUrl: '/Scripts',
paths: {
"jquery": "./jquery-1.7.1.min",
"jqx": "/Content/Plugins/jqWidgets",
"package" : "/Scripts/packages"
},
urlArgs: "bust=" + (new Date()).getTime(),
shim : {
'jqx/jqxcore': ['jquery'],
'jqx/jqxsplitter': ['jquery','jqx/jqxcore']
}
}
);
window.require(['jquery', 'layoutManager', 'container', 'package/ImagingX'],
function ($,lm,container,px) {
px.Focus();
$(document).ready(function () {
lm.Init(); // Sets up panes
container.Init(); //Set up the containers
});
});
Update 15/10/2012
I'm getting desperate to solve this issue now, I've stripped everything back to the basics so here is the new main file :
(function () {
requirejs.config({
paths: {
"packages": "packages"
}
});
require([
'packages/testmodule'
],
function (tm) {
alert(tm);
});
})();
And the module which is in a sub folder called packages.
define('testmodule',
function () {
alert("called");
return {
set : 'rar '
};
});
I can see the script loaded but it never gets executed, hence I never get a reference for it.
requirejs.config({
paths: {
//"jquery": "./jquery-1.8.2.min",
//"jqx": "/Content/Plugins/jqWidgets",
"templates": 'templates',
"text": "commonRequireJsModules/text",
"domReady": "commonRequireJsModules/domReady",
"packages" : 'packages/'
//'signalR': './jquery.signalR-0.5.3.min',
//'knockout': './knockout-2.1.0',
//'pubsub' : './pubsub'
}
//,urlArgs: "bust=" + (new Date()).getTime()
//,
//shim : {
// 'jqx/jqxcore': ['jquery'],
// 'jqx/jqxsplitter': ['jquery', 'jqx/jqxcore'],
// 'signalR': ['jquery'],
// 'pubsub' : ['jquery']
//}
});
The trailing slash on the packages path seems to have addressed the issue, in part with also removing the name in the define part of the module. So it now looks like
define(['deps'],function(deps){
});
Rather than
define('myMod',['deps'],function(deps){
});
Couple of things:
it seems strange to use window.require instead of just require
names in 'shim' must match names in 'paths', this is not the case, here
document.ready is done for free by require, no need to do it again
So: do you have any loading error in your JS console? Does it says a script is missing?
Here is a working require configuration, Router is in the same folder of this code:
require.config({
paths:{
'jquery':'lib/jquery.min',
'backbone':'lib/backbone.min',
'underscore':'lib/underscore.min',
'router':'Router'
},
shim:{
'backbone':{ deps:['jquery', 'underscore'] },
'router':{ deps:['backbone'] }
}
});
require(['router', 'jquery', 'underscore', 'backbone'],
function (Router) {
var router = new Router();
$('img').hide();
});
});
And the index.html:
<html>
<head>
<script data-main="assets/js/App.js" src="assets/js/lib/require.min.js"></script>
</head>
<body>...</body>
</html>