RequireJS replacing Node's Require method - node.js

I'm running into an issue where node's require method has been replaced by requirejs' require method. We're running a backbone app and I've set up some mocha tests. The goal was to be able to run the tests in the browser, and also use grunt-mocha-test and run them in terminal on every build with grunt-contrib-watch.
I don't fully yet understand how all these pieces fit together, so please forgive any lack of explanation, understanding.
This is the set up of one of our test files, models.js:
describe("Models", function() {
var should;
var firstModule = 'models/firstModel';
var secondModule = 'models/secondModel';
var chaiModule = 'chai';
modules = [
firstModule,
secondModule,
chaiModule
];
before(function(done) {
require(modules, function(firstModel, secondModel, chai){
FirstModel = eventModel;
SecondModel = eventDetailsModel;
should = chai.should();
done();
});
});
beforeEach(function(done) {
NewFirstModel = new FirstModel();
NewSecondModel = new SecondModel();
done();
});
describe("first model", function() {
it("should exist", function (done) {
NewFirstModel.should.exist();
done();
});
});
});
Using grunt-contrib-requirejs with these settings:
compile:
options:
baseUrl: "<%= tmpDir %>/scripts"
mainConfigFile: "<%= tmpDir %>/scripts/init.js"
name: "../../bower_components/almond/almond"
out: "<%= distDir %>/scripts/app.js"
preserveLicenseComments: false
cjsTranslate: true
wrapShim: true
uglify:
ascii_only: true
The mochaTest grunt task:
test:
options:
reporter: 'spec',
src: ['app/test/*.js']
I've got a test.html file which includes each individual test file and properly tests everything I throw at them.
However, when I run the mochaTest grunt task, which points to the same test files, I get the following error:
AssertionError: path must be a string
referring to this line in models.js:
require(modules, function(firstModel, secondModel, chai){
If I console log the require method, it comes back as RequireJS' require method. I've tried a few different things, including setting nodeRequire: require in the init.js file referenced in the requirejs config. Any clues? Thanks!!!

Related

Browsersync not reloading browser or injecting css

I've been trying to get this straight for a few days now but haven't been able to get it working the way I need to. I'm unable to find any examples of other people using Browsersync with .net core, that may even be the reason I'm experiencing all of these issues. But I can't find any evidence that proves that and wouldn't understand why exactly that would be the case.
Anyway... I've got everything working in my gulp file exactly how I want it to for sass/js for handling errors, etc. I'm not new to gulp otherwise I'd blame my lack of experience for my inability to get this working.
Here's my gulp file followed by what the output is when running gulp.
Default Task:
const gulp = require("gulp"),
uglify = require("gulp-uglify"),
sass = require("gulp-sass"),
rename = require('gulp-rename'),
sassGlob = require('gulp-sass-glob'),
postcss = require('gulp-postcss'),
autoprefixer = require('gulp-autoprefixer'),
sourcemaps = require('gulp-sourcemaps'),
cleanCSS = require('gulp-clean-css'),
concat = require('gulp-concat'),
msbuild = require('gulp-msbuild'),
through = require('through2'),
notifier = require('node-notifier'),
browserSync = require('browser-sync').create();
// Static Server + watching scss/html files
gulp.task('serve', ['sass', 'compileJS'], function() {
browserSync.init({
proxy : {
target: "https://localhost:3000",
},
files: ['./wwwroot/css/*'],
rewriteRules: [
{
match: new RegExp('/css/main.min.css'),
fn: function() {
return './wwwroot/css/main.min.css'
}
}
]
});
//Watch for any changes to the scss files.
gulp.watch('./wwwroot/sass/**/*.scss', ['sass']);
//Watch for any changes to the js files, reload after those changes are made.
gulp.watch('./wwwroot/js/source/*.js', ['compileJS']).on('change', browserSync.reload);
//Watch for any changes to a .cshtml file and reload the browser if/when that change happens.
gulp.watch("./**/*.cshtml").on('change', browserSync.reload);
});
gulp.task('default', ['serve']);
/**
* Compiles SASS files and stores the result into the public folder
*/
gulp.task('sass', function () {
return gulp.src('./wwwroot/sass/main.scss')
.pipe(sassGlob())
.pipe(sass().on('error', function (err) {
console.log('Sass Error:', err.toString());
notifier.notify({
'title': 'Gettin\' Sassy 💁‍♀️',
'message': 'You goofed. Check your terminal window for more information.'
});
this.emit("end");
}))
.pipe(postcss([require('autoprefixer')]))
.pipe(
autoprefixer({
browsers: ['last 2 versions'],
cascade: false
})
)
.pipe(
through.obj(function(chunk, enc, cb) {
cb(null, chunk)
})
)
.pipe(cleanCSS({compatibility: 'ie8',
level: 2}))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('./wwwroot/css'))
.pipe(browserSync.stream());
});
/**
* Compiles the Javascript files and stores the result in the public folder
*/
gulp.task('compileJS', function (done) {
return gulp.src('./wwwroot/js/source/*.js')
.pipe(sourcemaps.init())
.pipe(concat('main.js'))
.pipe(uglify().on('error', function (err) {
console.log('JS Uglify Error:', err.toString());
notifier.notify({
'title': 'JS Compile Error',
'message': 'Something about your JS is a little off. Check yourself before you wreck yourself.'
});
this.emit("end");
}))
.pipe(rename({suffix: '.min'}))
.pipe(sourcemaps.write('../maps'))
.pipe(gulp.dest('./wwwroot/js/dist'));
});
Output:
$ gulp
[21:34:15] Using gulpfile
~/Repos/PROJECT_DIRECTORY/PROJECT_NAME/gulpfile.js
[21:34:15] Starting 'sass'...
[21:34:15] Starting 'compileJS'...
[21:34:15] Finished 'sass' after 437 ms
[21:34:15] Finished 'compileJS' after 426 ms
[21:34:15] Starting 'serve'...
[21:34:16] Finished 'serve' after 1 s
[21:34:16] Starting 'default'...
[21:34:16] Finished 'default' after 68 μs
[Browsersync] Proxying: https://localhost:3000
[Browsersync] Access URLs:
------------------------------------
Local: https://localhost:3000
External: https://10.0.0.137:3000
------------------------------------
UI: http://localhost:3001
UI External: http://localhost:3001
------------------------------------
[21:34:35] Starting 'sass'...
[Browsersync] 1 file changed (main.min.css)
[21:34:35] Finished 'sass' after 207 ms
[21:34:58] Starting 'compileJS'...
[21:34:58] Finished 'compileJS' after 154 ms
[Browsersync] Reloading Browsers...
So, looking at that output you would probably think to yourself, "This dude is an idiot... Browsersync states that it's reloading browsers..." Right, it does state that, but it is not reloading the browser. Browsersync also fails to inject my css into the browser as well.
As I mentioned, I've used gulp before, and this setup closely represents the gulp files that I use when doing Wordpress development as well. However, it won't work for this project (which has led me to my .net core / Visual Studio suspicions).
You could just do something like this
Create a env variable thats global to your application then above the closing tag in your view you can add the following code.
This code is how I do it in Laravel with my Blade templates but it should be exactly the same you just need to replace it with the way .NET does it, I think they use Razor templating engine :)
{{-- Live reload with browser sync --}}
#if (!empty(env('APP_ENV')) && env('APP_ENV') === 'local')
<script
async
defer
src="{{ URL::to('/') . ':3000/browser-sync/browser-sync-client.js?v=2.26.7'}}">
</script>
#endif
Hope this helps you.
Just for interest sake below is my gulp pipeline:
const browserSync = require("browser-sync");
const sass = require("gulp-sass");
const autoprefixer = require("gulp-autoprefixer");
const sourcemaps = require("gulp-sourcemaps");
const rename = require("gulp-rename");
const reviser = require("gulp-rev");
const runSequence = require("run-sequence");
gulp.task("browserSync", function() {
return browserSync.init({
open: false,
https: false,
notify: false,
injectChanges: true,
proxy: "http://{site-name-here}.local/",
});
});
gulp.task("compile:scss", function() {
return (
gulp
// Gets the main.scss file
.src("resources/assets/scss/main.scss")
// Passes it through a gulp-sass, log errors to console
.pipe(sass().on("error", sass.logError))
// Adds versioning
.pipe(reviser())
// Add vendor prefixes
.pipe(
autoprefixer({
browsers: ["last 2 versions"],
cascade: false
})
)
// Rename the file
.pipe(rename({ suffix: ".min" }))
// Outputs it in the css folder
.pipe(gulp.dest("public/css"))
// Add sourcemaps
.pipe(sourcemaps.write())
// Adds versioned file to manifest so we can access with the same name
.pipe(reviser.manifest("manifest/rev-manifest.json"), { merge: true })
// Outputs it in the css folder
.pipe(gulp.dest("public/css"))
.pipe(
browserSync.reload({
// Reloading with Browser Sync
stream: true
})
)
);
});
// Watchers
gulp.task("watch", function() {
gulp.watch(["./resources/assets/scss/**/*"], "compile:scss", browserSync.reload);
});
// Default task
gulp.task("start", function(callback) {
return runSequence(
"browserSync",
"compile:scss",
"watch",
callback
);
});
to use it I just run gulp start
Keep in mind that running gulp like this you will need to have gulp installed globally. to do this run npm install --global gulp-cli

browser sync reloading injecting works, but reloads after

it seems there is something im missing - Im just trying to get the css injection working on this project.
The server proxy works
The file watcher too
The injection works,
but the page always reloads half a second after...
Im on Mac osx 10.11.6 (15G1108)
Node v4.1.1
here is my gulpfile:
var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var reload = browserSync.reload;
var sass = require('gulp-sass');
var plumber = require('gulp-plumber');
var notify = require("gulp-notify");
var src = {
scss: 'assets/scss/**',
css: 'assets/css/',
html: 'app/*.html'
};
gulp.task('serve', ['sass'], function() {
browserSync.init({
proxy: "intouch.local",
open: false,
reloadOnRestart: false,
injectChanges: true,
});
gulp.watch(src.scss, ['sass']);
});
gulp.task('sass', function() {
var onError = function(err) {
notify.onError({
title: "Gulp",
subtitle: "Failure!",
message: "Error: <%= error.message %>",
sound: "Beep"
})(err);
this.emit('end');
};
return gulp.src(src.scss)
.pipe(plumber({errorHandler: onError}))
.pipe(sass())
.pipe(gulp.dest(src.css))
// NOTE: i've tried with all of these lines, all do the same...
// .pipe(reload({stream: true}))
// .pipe(browserSync.stream())
.pipe(browserSync.reload({
stream: true
}))
.pipe(notify({
title: 'Gulp',
subtitle: 'success',
message: 'Sass task',
sound: "Pop"
}));
});
gulp.task('default', ['serve']);
Adjust the glob for the sass files you want to compile to only match .scss (or .sass) files:
e.g. in your code example change assets/scss/** to assets/scss/**/*.scss.
A broad glob can result in unexpected files (typically source maps) being passed down the pipeline and Browsersync's default behaviour when it encounters modified files that can't be streamed is to reload the page, hence you get a successful injection for the CSS and then a hard reload for some files you probably didn't expect / don't care about.

Failed to load resource: the server responded with a status of 404 (Not Found) requirejs+karma

I am facing issue to load test file from another directory to my unit test file. i am using requirejs and karma another question is it right way to load chai-http module in test scenario file project
|--service
|--abcfile.js // i want to use method implemented in this file and
test it.
|---node_modules
-- all node library like karma,chai module
|--test-main
|--test-main.js
| karma.conf.js
Karma.conf.js
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['mocha', 'requirejs'],
files: [
{pattern: 'node_modules/**/*.js', included: false},
{ pattern: 'node_modules/**/*/*.js', included: false },
'test/test-main/test-main.js',
{ pattern: 'test/test-main/*.js', included: false }
],
exclude: [
],
reporters: ['progress','html'],
htmlReporter: {
outputFile: 'test/report/units.html',
pageTitle: 'Tests',
subPageTitle: 'A sample project description'
},
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
captureTimeout: 60000,
singleRun: false
});
};
test-main
(function() {
var specFiles = null;
var baseUrl = '';
var requirejsCallback = null;
if (typeof window != 'undefined' && window.__karma__ != undefined) {
baseUrl = '/base';
requirejsCallback = window.__karma__.start;
specFiles = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
if (/.*\/javascript\/*\/.+_Test\.js$/.test(file)) {
specFiles.push(file);
}
}
}
}
requirejs.config({
baseUrl: baseUrl,
paths: {
'chai': './node_modules/chai/chai',
'sinon': './node_modules/sinon/pkg/sinon',
'chaiHttp': './node_modules/chai-http/dist/chai-http',
},
deps: specFiles,
callback: requirejsCallback
});
})();
user test scenario file
define(function (chai, sinon, chaiHttp) {
var expect = chai.expect;
var service= require('/service/abcfile.js');// this is file where i want one of the function to test
chai.use(chaiHttp);
Error
Failed to load resource: the server responded with a status of 404 (Not Found)
If you want to use the CommonJS sugar you have to define your module using define(function(require, exports, module) {... and it looks to me that the path of the module currently failing should be service/abcfile' (no .js extension needed or desirable, and no leading slash). So something like this:
define(function(require, exports, module) {
var chai = require("chai");
var sinon = require("sinon");
var chaiHttp = require("chaiHttp");
var expect = chai.expect;
var service= require('service/abcfile');// this is file where i want one of the function to test
chai.use(chaiHttp);
You could omit exports and module from the callback passed to define if you end up not using them.

Requirejs do not add ".js" for modules using karma

I have simple test, that must work in webstorm using karma and requirejs.
The problem is that for some reason requirejs do not add ".js" for modules i was loading for tests. So it crashed trying to load "../ts/mamats/mama", while "../ts/mamats/mama.js" exists
Test (main.jasmine.js):
define(["require", "exports", "../ts/mamats/mama"], function(require, exports, mama) {
describe("first test", function () {
it("should be true", function () {
var object = new mama.block();
expect(object instanceof mama.block).toBe(true);
});
});
});
//# sourceMappingURL=main.jasmine.js.map
every thing works correctly when i replace "../ts/mamats/mama" with "../ts/mamats/mama.js"
sourceMappingURL here because javaScript file generated from typeScript source file, and because of that i cannot add ".js" for modules manually
Test starts with this entry point (main-test.js):
var tests = Object.keys(window.__karma__.files).filter(function (file) {
return (/\.jasmine\.js$/).test(file);
});
requirejs.config({
baseUrl: '/base',
deps: tests,
callback: window.__karma__.start
});
Why requirejs don't add ".js" for modules here?
Karma conf file:
module.exports = function(config) {
config.set({
basePath: '../',
frameworks: ['jasmine', 'requirejs'],
files: [
'static-tests/main-test.js',
{ pattern: 'static/**/*', included: false },
{ pattern: 'static-tests/**/*', included: false }
],
exclude: [],
preprocessors: {},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
singleRun: false
});
};
Here is an interesting read on how RequireJs handles this:
http://requirejs.org/docs/api.html#jsfiles
Reading that makes it seem like an issue with RequireJS, but there seems to be some debate on whether or not that is true. Regardless, this gist seems to solve the issue.
var tests = Object.keys(window.__karma__.files).filter(function (file) {
return /\.spec\.js$/.test(file);
}).map(function(file){
return file.replace(/^\/base\/src\/js\/|\.js$/g,'');
});
require.config({
baseUrl: '/base/src/js'
});
require(tests, function(){
window.__karma__.start();
});
It looks like trouble in require.js
The problem is in next:
1. When in deps appear absolute path - requirejs stop add ".js" for any require call
2. When in deps appear file with extension, for some reason requirejs again stop add ".js" for modules
Other Solution here - to replace bathUrl and add it to requirejs conf do not help.
For me solution is next:
var tests = Object.keys(window.__karma__.files).filter(function (file) {
return (/\-jasmine\.js$/).test(file);
}).map(function (file) {
return file.replace(/^\/|\.js$/g, '');
});
and
baseUrl: '',
for requirejs.conf
and i have no idea why requirejs still add "/base" for all url that are requested, but now all works fine

Load files in specific order with RequireJs

I'm new to RequireJS and I'm stuck with the loading order.
I have a global project configuration that I need to be loaded before the modules located in js/app/*.
Here's my struture :
index.html
config.js
js/
require.js
app/
login.js
lib/
bootstrap-2.0.4.min.js
Here's the config.js file :
var Project = {
'server': {
'host': '127.0.0.1',
'port': 8080
},
'history': 10, // Number of query kept in the local storage history
'lang': 'en', // For future use
};
And here's my requirejs file (app.js) :
requirejs.config({
//By default load any module IDs from js/lib
baseUrl: 'js/lib',
//except, if the module ID starts with "app",
//load it from the js/app directory. paths
//config is relative to the baseUrl, and
//never includes a ".js" extension since
//the paths config could be for a directory.
paths: {
bootstrap: '../lib/bootstrap-2.0.4.min',
app: '../app',
},
shim: {
'app': {
deps: ['../../config'],
exports: function (a) {
console.log ('loaded!');
console.log (a);
}
} // Skual Config
},
});
var modules = [];
modules.push('jquery');
modules.push('bootstrap');
modules.push('app/login');
// Start the main app logic.
requirejs(modules, function ($) {});
But sometimes, when I load the page, I have a "Project" is undefined, because login.js has been loaded BEFORE config.js.
How can I force config.js to be loaded at first, no matter what ?
Note: I saw order.js as a plugin for RequireJS but it's apparently not supported since the v2, replaced by shim.
Ran into a similar problem today - we have bootstrapped data that we want to make sure is loaded before anything else, and that the module exposing that data is set up before any other modules are evaluated.
The easiest solution I found to force load order is to simply require a module be loaded before continuing on with app initialization:
require(["bootstrapped-data-setup", "some-other-init-code"], function(){
require(["main-app-initializer"]);
});
There's a possible solution to build a queue for modules to be loaded. In this case all modules will be loaded one-by-one in exact order:
var requireQueue = function(modules, callback) {
function load(queue, results) {
if (queue.length) {
require([queue.shift()], function(result) {
results.push(result);
load(queue, results);
});
} else {
callback.apply(null, results);
}
}
load(modules, []);
};
requireQueue([
'app',
'apps/home/initialize',
'apps/entities/initialize',
'apps/cti/initialize'
], function(App) {
App.start();
});
You won't have to worry about the load order if you define your js files as AMD modules. (Or you can use the shim config if you can't modify the config.js and login.js to call define).
config.js should look something like this:
define({project: {
'server': {
'host': '127.0.0.1',
'port': 8080
},
'history': 10, // Number of query kept in the local storage history
'lang': 'en', // For future use
}});
login.js:
define(['jquery', '../../config'], function($, config) {
// here, config will be loaded
console.log(config.project)
});
Again, shim config should only be used if calling define() inside the modules is not an option.

Resources