Backbone + Webpack `Uncaught TypeError: _.create is not a function`, underscore not loading? - backbone.js

I'm using webpack for the first time. When requiring backbone, it seems to not be loading underscore properly, since I'm getting the error Uncaught TypeError: _.create is not a function in backbone.js:1892 in my browser.
main.js
'use strict';
import Backbone from 'backbone';
Backbone.$('body'); // Doesn't error
Backbone.View.extend({}); // Gives error
My webpack config can be found in this boilerplate repo.
└─┬ backbone#1.3.3
└── underscore#1.8.3
*Update* When I use backbone v1.2.3, it works fine. v1.3.0+ causes this error.

Turns out it was an issue due to npm3's method of loading dependencies, combined with my webpack config.
I was using a directory for the modulesDirectories property.
modulesDirectories: [
path.join(__dirname, 'node_modules')
]
Since npm3 loads dependencies in a flat way (all at the root node_modules dir, and version conflicts get put into the module's directory under a node_modules subdir, webpack was always importing underscore 1.7.x (a dependency of another module in my project) instead of the 1.8.3 that was in backbone's subdir.
Downgrading to backbone v1.2.3 only worked because it was using the same version of underscore that my other dependency was using, so there was no conflict.
I removed the modulesDirectories completely, since it has a default. I could have also changed this to modulesDirectories=['node_modules'] to get the same effect.

Related

Angular 2 CLI and yfiles for HTML 2.0.0 - Cannot read property 'GraphComponent' of undefined

THE PROBLEM
I am trying to integrate yfiles for HTML into an Angular 2 application that uses the Angular CLI. I am using the latest version of Angular 2 and the latest BETA release of the CLI.
I have installed the types using npm install --save #types/yfiles.
I have placed the required yfiles folders in my project and have updated angular-cli.json to include the required sytles and scripts:
"styles": [
"../lib/yfiles.css"
],
"scripts": [
"../lib/license.js",
"../lib/yfiles/view-component.js",
"../lib/yfiles/view-layout-bridge.js",
"../lib/yfiles/layout-hierarchic.js",
"../lib/yfiles/layout-tree.js",
"../lib/yfiles/router-polyline.js",
"../lib/yfiles/router-other.js"
],
I have confirmed that a build includes these scripts in the bundled scripts output after running ng build.
When trying to reference yfiles the autocomplete works in the IDE (latest Webstorm):
graphComponent: yfiles.view.GraphComponent;
constructor(private element: ElementRef,
injector: Injector,
resolver: ComponentFactoryResolver) { }
ngAfterViewInit() {
let containerDiv:HTMLDivElement =
this.element.nativeElement.getElementsByClassName('graph-control-container')
[0];
this.graphComponent = new yfiles.view.GraphComponent(containerDiv);
}
The project compiles and runs when ng serve is issued BUT when I navigate to a route that activates the component that is trying to use yfiles, an error is thrown and reported in the console:
error_handler.js:54 EXCEPTION: Uncaught (in promise): Error: Error in ./BrowseVisualisationsComponent class BrowseVisualisationsComponent - inline template:0:0 caused by: Cannot read property 'GraphComponent' of undefined
I have tried importing the yfiles modules - for example:
import 'yfile/view-component'
This just prevents ng serve from building the application:
ERROR in ./src/app/shared/table-relationship-visualisation/table-relationship-visualisation.component.ts
Module not found: Error: Can't resolve 'yfiles/view-component' in '/home/VMdev/Documents/iotahoe_client/src/app/shared/table-relationship-visualisation'
# ./src/app/shared/table-relationship-visualisation/table-relationship-visualisation.component.ts 12:0-31
# ./src/app/app.module.ts
# ./src/main.ts
# multi main
Any assistance appreciated.
The scripts provided in the app.scripts array will just be loaded as if they would have been referenced with regular <script> tags - no module resolving will take place at all.
However, the yFiles modules you provided in the scripts array are "meta modules" that would load the actual implementation files using AMD/CommonJS-style define/require statements.
Therefore, in order to load the yFiles functionality with angular-cli, you will have to provide the actual implementation files directly:
"scripts": [
"./assets/yfiles/license.js",
"./assets/yfiles/lib/yfiles/impl/lang.js",
"./assets/yfiles/lib/yfiles/impl/graph-core.js",
"./assets/yfiles/lib/yfiles/impl/core-lib.js",
"./assets/yfiles/lib/yfiles/impl/graph-styles-core.js",
"./assets/yfiles/lib/yfiles/impl/graph-styles-default.js",
"./assets/yfiles/lib/yfiles/impl/algorithms.js",
"./assets/yfiles/lib/yfiles/impl/graph-styles-template.js",
"./assets/yfiles/lib/yfiles/impl/graph-styles-other.js",
"./assets/yfiles/lib/yfiles/impl/graph-binding.js",
"./assets/yfiles/lib/yfiles/impl/layout-core.js",
"./assets/yfiles/lib/yfiles/impl/graph-layout-bridge.js",
"./assets/yfiles/lib/yfiles/impl/layout-polyline.js",
"./assets/yfiles/lib/yfiles/impl/layout-router.js",
"./assets/yfiles/lib/yfiles/impl/layout-tree.js",
"./assets/yfiles/lib/yfiles/impl/layout-hierarchic.js"
],
It's unfortunate that the modules can't be resolved automatically with this approach even though the yFiles modules adhere to the UMD pattern, but I don't see a better option to make this work with angular-cli right now.
To generate the list of the yFiles implementation modules in the correct order, you can use our yeoman generator with the "script-tags" option:
https://www.npmjs.com/package/generator-yfiles-app

Bundling textAngular and angular-sanitize with webpack

I'm currently in the process of migrating a project (ng 1.5.8) from gulp pipeline to webpack.
I'm facing an issue where textAngular gives me the following error message Module 'ngSanitize' is not available.
if I add a require('angular-sanitize') before the require('textangular') then I get the following error message The textAngular-sanitize provider has been replaced by another -- have you included angular-sanitize by mistake?
I've tried playing with the externals of my webpack config with no luck so far. I've also tried using angular-module-sanitize, didn't work either.
So here is my question: how can I configure properly webpack + my requires so textAngular has the proper dependencies provisionned?
Thanks!
finnaly got it to work.
The solution is to:
- not require angular-sanitize
- not do anything special to the webpack config
- use these lines to require text angular instead (the generic one was including to much stuff)
require('../../node_modules/textangular/dist/textAngular-sanitize.min');
require('../../node_modules/textangular/dist/textAngular.umd');

Webpack - WARNING: Tried to load angular more than once. Angular JS

I have built 3 separate npm modules with webpack.
They all have a dependency on angular because I have the line:
var angular = require('angular');
in the angular module definitions for each npm module.
One of the modules has a dependency on the other 2:
var angular = require('angular');
var ngModule = angular.module('topModule', [
require('dependency1'),
require('dependency2')
]);
I believe the reason I'm getting the tried to load angular more than once error is because Angular has been included in all 3 of the bundles built by webpack.
I understand that I could have configured webpack to put angular in a separate file (e.g. vendor.js), but I thought that when I built the top level file, it would see that Angular was already included by the other 2 modules and wouldn't add it again.
How do I use `require('angular')' in all of the modules, but only have it included once in the top level module?
I had this issue as well. For me, it ended up being that I was using the html-webpack-plugin and passing in my own template, like so in my webpack.config.js:
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
}),
],
In this template file, I had the line:
<script src="bundle.js"></script>
This line is automatically injected by html-webpack-plugin, and therefore I was loading my bundle twice. See plugin docs here.
Hope this helps!
For those who use npm, webpack encore in Symfony
with multiple local packages bootstrapped by Lerna:
(webpack.config.js)
...
const path = require('path');
...
Encore
...
.addAliases({
'angular': path.resolve(path.join(__dirname, 'node_modules', 'angular'))
})
...
It will refer all require 'angular' to the root node_module folder.
Just don't forget to add angular to your package.json in root and run 'npm install'. As for the local packages, 'lerna bootstrap', 'lerna exec npm install', 'npm run encore {desire enviroment}'

Ag-grid not working with angular and webpack

I am trying to get ag-grid to work with webpack.
I've done the standard thing by adding ag-grid through npm and added the reference to webpack.config by doing this:
resolve: {
alias: {"ag-grid" : path.resolve(__dirname, "./node_modules/ag-grid/dist/ag-grid.js")
}
The file gets resolved and loaded into the index file just fine. And I've done the following for angular.
angular.module("cs-app", [require("ag-grid").name]);
Webpack also resolves this file and gets included and loaded up but when I run the app I get the following error.
[$injector:modulerr] Failed to instantiate module angularGridGlobalFunction due to:
[$injector:nomod] Module 'angularGridGlobalFunction' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
I can't find the name angularGridGlobalFunction in ag-grid.js but when I comment out the reference to ag-grid then the app works just fine.
So anyone suggestions?
so ag-grid does not need aliasing in the webpack.config.js so I removed that and aliased the node_modules folder.
resolve : {
alias : {
// bind version of jquery-ui
"jquery-ui" : "jquery-ui/jquery-ui.js",
// bind to modules;
modules : path.join(__dirname, "node_modules"),
components : path.join(__dirname, "components"),
libs : path.join(__dirname, "bower_components"),
}
},
I add at the top of my module file
require("ag-grid");
require("modules/ag-grid/dist/ag-grid.css");
require("modules/ag-grid/dist/theme-fresh.css");
And changed the angular module reference
angular.module("cs-app", ["agGrid"]);
And whatta you know it worked
If you like it hit me with an upvote! Thanks
Here is what worked for me, first the solution:
npm install imports-loader --save-dev
Then in my code, add this to the loaders array in the webpack-config.js
{ test: require.resolve("ag-grid"), loader: "imports?importedAngular=angular" },
then the problem:
The ag-grid in npm in npm is not "npm ready", there is no indication in the code that ag-grid requires("angular"). So webpack is free to put it anywhere in the file, and load it any time. In my case, when ag-grid loaded, angular and window.angular were undefined, so ag-grid loaded before angular. The ag-grid checks that window.angular is defined before it creates the module, so the module is never created.
The steps above add a shim, to always load angular before ag-grid.

$injector nomod Module 'angularFileUpload' is not available

I'm currently using the mean.io stack for a personal project and everything runs smoothly locally. I tried to deploy to Heroku and I'm having problems with one module not instantiating properly! I found similar questions here on Stack Overflow, but none of the answers worked for me.
Here's my error:
Error: [$injector:modulerr] Failed to instantiate module mean due to:
[$injector:modulerr] Failed to instantiate module angularFileUpload due to:
[$injector:nomod] Module 'angularFileUpload' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument. (dist.min.js)
It seems like my module is not loading. But according to the logs, it installed properly:
mean#0.3.3 postinstall /tmp/build_5d155aeb-14b5-4414-af19-986a68df3b19
node node_modules/bower/bin/bower install
bower ng-file-upload-shim#* not-cached git://github.com/danialfarid/angular-file-upload-shim-bower.git#*
bower ng-file-upload-shim#* resolve git://github.com/danialfarid/angular-file-upload-shim-bower.git#*
bower angular#* not-cached git://github.com/angular/bower-angular.git#*
bower angular#* resolve git://github.com/angular/bower-angular.git#*
...
bower ng-file-upload#* not-cached git://github.com/danialfarid/angular-file->upload-bower.git#*
bower ng-file-upload#* resolve git://github.com/danialfarid/angular-file->upload-bower.git#*
...
bower ng-file-upload-shim#* install ng-file-upload-shim#1.4.0
bower ng-file-upload#* install ng-file-upload#1.4.0
...
bower angular#1.2.19 install angular#1.2.19
...
Done, without errors.
Note: angularFileUpload by Danial Farid requires that the shim.js file is loaded before angular, which in turn gets loaded before angularFileUpload. Seems like angular got installed afterwards, would that be a problem?
Here's my module, where I declare dependency:
angular.module('mean.thingy', ['angularFileUpload','ngAnimate']).controller(...
and finally, my assets.json:
"js": {
"public/build/js/dist.min.js": [
"public/system/lib/jquery/dist/jquery.min.js",
"public/system/lib/angular-file-upload-master/dist/angular-file-upload-shim.js",
"public/system/lib/angular/angular.js",
...
"public/system/lib/angular-file-upload-master/dist/angular-file-upload.js",
"public/init.js",
"public/*/*.js",
"public/*/{controllers,routes,services}/*.js"
]
}
I'd appreciate any help or hunches that you may have! Thanks!
I got the same error and it got fixed by adding the file path to karma.conf.js
I had this same problem, I am using mean.js rather that mean.io so might be slightly different.
You were on the right track when you asked "Seems like angular got installed afterwards, would that be a problem?" I believe so.
To fix this, make sure that in your production.js config you put the scripts in the right order as well as in all.js e.g.
'public/lib/ng-file-upload/FileAPI.min.js',
'public/lib/ng-file-upload/angular-file-upload-shim.min.js',
'public/lib/angular/angular.js',
'public/lib/ng-file-upload/angular-file-upload.min.js',
Change your upload dependency declaration to:
angular.module('mean.thingy', ['ngFileUpload','ngAnimate'])...
In my case it was because my local copies of angular-file-upload-shim.min.js and angular-file-upload.min.js were corrupted (I did not fetch them using bower).
Try downloading the raw .js files from the author's github page: https://github.com/danialfarid/angular-file-upload/tree/master/dist , click on the file, click on "Raw", then point your JS file to the local copies of these files.

Resources