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

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

Related

Webpack not resolving relative paths in imported CSS files

I am currently working on building a set of UI modules that developers can use to create content on their sites (similar to Bootstrap, Foundation etc). Each UI module is created as its own npm package and a developer will then pull the required modules into their project via npm.
I have a components-accordion package which contains just the CSS for an accordion. It has a file structure as follows:
/lib
/build
/node_modules
index.css
package.json
The index.css file shown above consists of a relative link to the lib directory where the actual styles for the component live:
./lib/accordion.css
I have been testing this package with a React Accordion project and have imported it for the styles. However the relative paths in this package seem to not be correctly resolved by Webpack.
import "components-accordion";
gives an error:
Failed to compile.
./src/components/Accordion.js
Module not found: Can't resolve 'components-accordion' in ...
If I link to the index.css file directly:
import "components-accordion/index.css";
../components-accordion/index.css
Module not found: Can't resolve './lib/accordion' in...
Any ideas would be great.
Thanks
Update your webpack configuration to include the lib folder as part of webpack modules, using path
const path = require("path");
resolve: {
modules: [
'node_modules',
path.resolve(__dirname, 'lib')
]
},

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

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.

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.

Webpack with bower support

Would I like to load preferably the node packages, and only if not exist, loads the bower package.
I would just use the node package only as recommended in Webpack site, but I need to load a library that is just in bower, https://github.com/Stamplay/stamplay-js-sdk and https://github.com/Stamplay/angular-stamplay
Try with bower-webpack-plugin
I installed https://github.com/lpiepiora/bower-webpack-plugin
But when I run webpack-dev-server -d --watch the error is displayed in chrome console:
Uncaught TypeError: angular.module is not a function(anonymous function) # app.js:8__webpack_require__ # bootstrap 6cecf8d96fb5a1205f10:19(anonymous function) # bootstrap 6cecf8d96fb5a1205f10:39__webpack_require__ # bootstrap 6cecf8d96fb5a1205f10:19(anonymous function) # bootstrap 6cecf8d96fb5a1205f10:39(anonymous function) # bootstrap 6cecf8d96fb5a1205f10:39
angular.js:68Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
Error: [$injector:nomod] Module 'app' 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.
Try with ResolverPlugin (see Webpack docs)
In webpack.config i add..
plugins: [
...
, new webpack.ProvidePlugin({
Q: 'q',
store: 'store.js',
Stamplay: 'stamplay-js-sdk'
})
, new webpack.ResolverPlugin(
[
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
], ["normal", "loader"]
)
],
....
resolve: {
root: [
path.join(__dirname, 'node_modules'),
path.join(__dirname, 'bower_components')
],
But, like mention here the Stamplay object is not correct!
Trying with CDN and angular-webpack-plugin
First add script tag into index.html ..
Second, add externals in webpack.config ..
externals: {
stamplay: 'Stamplay'
},
And finally .. new AngularPlugin into plugins on webpack.config
This way, worsks but I cant use angular-stamplay, when I try, a error in module stamplay apper. :(
See branch with this change here
The full project is here: https://github.com/Ridermansb/webpackBowerStarter
Ok, tried your project from git https://github.com/Ridermansb/webpackBowerStarter
And as mentioned at https://github.com/lpiepiora/bower-webpack-plugin/issues/20 I too had that Cannot resolve module 'stamplay-js-sdk' issue , then in webpackBowerStarter directory I did bower install stamplay-js-sdk then sudo npm run build and voila! It was done.
On npm run start which is same as webpack-dev-server -d --watch I get http://localhost:8080/webpack-dev-server/ like
And console says
sry if u meant something else. Does this resolves your issue ?

How to let Webpack require a root node_module instead of an child package?

I have installed backbone and backbone.babysitter trough npm. When I use backbone in my scripts like this: import Backbone from "backbone"; It loads the installed backbone version 1.2.1. This works fine until I want to use backbone.babysitter. When backbone.babysitter loads it needs to add properties to backbone itself. But the package of backbone.babysitter imports its own backbone as dependency in his own node_modules folder, this backbone is on 1.2.0. So it attaches his methods to a different backbone i am working with.
How can I force Webpack to require the backbone from the root node_modules folder for backbone.babysitter?
Found a workaround here
module.exports = {
resolve: {
alias: {
'backbone': require.resolve('backbone')
}
}
}
You can use NormalModuleReplacementPlugin to rewire all require('backbone') towards your root backbone module.
plugins: [
new webpack.NormalModuleReplacementPlugin(/^backbone$/, require.resolve('backbone')),
],

Resources