Failed to load angularjs $templateCache template on dependencies with webpack - angularjs

Sorry for such a similar question to others out there, but I cant seem to make any of them work.
I understand that when using webpack, the standard way of incluing templates in your angular application is via the require. ie
template: require('./sometemplte.html')
I have done that in all of my app code and that works fine.
But i have four dependent libraries that use templateUrl, lets focus on angular-ui-boostrap.
my webpack.conf.js
entry: {
vendor: "./src/vendor.ts",
app: "./src/ClientApp/app.ts"
},
output: {
filename: "[name].js",
path: __dirname + "/wwwroot"
},
module: {
rules: [
{ test: /\.ts$/,
loader: "ts-loader"
}, {
test: /\.html$/,
loader: 'raw-loader'
}
inside vendor.ts i have
require('angular');
require('angular-ui-bootstrap');
and inside my app i am simply using the directive
<uib-typeahead></uib-typeahead>
the code inside my node_modules is not code that I can to modify. But currently i am getting the following error
angular.js:14700 Error: [$compile:tpload] Failed to load template: uib/template/typeahead/typeahead-popup.html
http://errors.angularjs.org/1.6.6/$compile/tpload?p0=ui-grid%2Fui-grid&p1=undefined&p2=undefined
I verified that the template is within $templateCache in my app. but for whatever reason it is not available for $compile to do its thing.
So how can i get $templateCache to work with webpack so my external dependencies will work?
Thanks in advance.

Thanks to John Reilly i finally figured it out.
There is a plugin called splitChunks , which use to be CommonsChunksPlugin. Once i inlcuded that into my configuration everyting just worked. I just used the default configuation mentioned here
https://webpack.js.org/plugins/split-chunks-plugin/
note: although it is a plugin, it does not go in the plugins array. it goes into the optimization object.
entry: {...},
output: {...},
optimization: {
splitChunks: {
chunks: "async",
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}

Related

Webpack build for exisitng AngularJS project

I am looking to migrate the existing Ruby based build system in our AngularJS(1.4.X) project to Webpack. The project code is not using JS modules and being with old-school Angular code patter I am not sure how Webpack will find all the controller and factory files in the project.
Folder structure is like,
-app
- assets
- javascripts
- ctrl
- controllerA.js
- controllerB.js
-services
-serviceA.js
-serviceB.js
- angular.min.js
- angular-route.js
- main.js
Wen I use the main.js in my entry point it get copied into the build folder but none of the other files as processed by Webpack even if I use babel-loader to .js rule.
One option I can think of is to use all other files into a separate bundle file using something like
https://www.npmjs.com/package/webpack-merge-and-include-globally, but I want to know whether there is a better way of doing it.
My current webpack config is as below.
module.exports = {
context: __dirname +'/app',
entry: {
'app-portal': [
'/assets/javascripts/main.js',
'/assets/javascripts/angular.min.js',
'/assets/stylesheets/portal/style.css',
'/assets/stylesheets/portal/navbar.css',
'/assets/stylesheets/portal/animation.css',
'/assets/stylesheets/portal/bootstrap.min.css',
'/assets/stylesheets/portal/bootstrap-notify.css',
'/assets/stylesheets/portal/fontello.css',
]
},
output: {
path: __dirname + "/dist/assets",
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader:'css-loader',
options: {
sourceMap: true,
url: false,
},
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './views/portal/index.html',
filename: '../index.html',
}),
new MiniCssExtractPlugin({
filename: './[name].css',
linkType: false,
ignoreOrder: false,
}),
new CopyPlugin({
patterns: [
{
from: './views/portal/**/*.*',
to: "../[name].[ext]",
globOptions: {
ignore: [
'**/index.*',
],
},
},
{
from: './assets/fonts/*.*',
to: "./[name].[ext]",
},
{
from: './assets/images/portal/*.*',
to: "./[name].[ext]",
},
{
from: './assets/theme/*.*',
to: "./[name].[ext]",
}
]
}),
],
Probably Webpack is not the right solution for me as I don;t want to change the source code as suggested in Webpack plugins and/or strategies for AngularJS
You can try something like this (we use it for running tests):
bundle.js:
const jsConext= require.context('.', true, /\.js/);
ng1Context.keys().forEach(ng1Context);
const cssConext= require.context('.', true, /\.css/);
ng1Context.keys().forEach(ng1Context);
...
entry: { 'app-portal': 'bundle.js' }
This should work in general (You might need fix order for css or in case of multiple angular modules etc.)

Webpack-dev-server shows full app with proper routing, but routing doesn't work on localhost

I am working on what should be a simple react application for a company (so I can't post very much code), and have been using webpack-dev-server for hotswapping to make development go more quickly. When I run my app on webpack-dev-server for development purposes, I am able to use the entire application with routing working as it should in production. When I tried to run my same application on localhost:8080, I am able to see my basic login screen and then home page, but after that point, none of the routing works and I consistently see "Cannot get /home", etc. which is a new behavior.
Every stack overflow question I've found has been addressing the exact opposite problem, where webpack-dev-server is not showing everything localhost is, and nothing I've found and tried has worked.
I have already tried regenerating the bundle.js to make sure that all of the changes were picked up, and I have gone over my webpack.config.js to make sure nothing has changed there (other than my additions to support hotswapping that I made weeks ago). Chrome Inspector shows no errors, so I'm really at a loss as to why the app is broken on localhost but not on webpack-dev-server.
In the end, all I want is for my react app to look the same on localhost as it does on the dev server, and for the life of me I can't figure out why it doesn't.
webpack.config.js:
module.exports = {
entry: [
'./src/index.js'
],
output: {
path: __dirname+'/public',
publicPath: '/',
filename: 'bundle.js'
},
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-1']
}
},{
test: /\.(s*)css$/,
loader: combineLoaders([
{
loader: 'style-loader'
}, {
loader: 'css-loader',
query: {
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}, {
loader: 'sass-loader'
},
])
},
],
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devServer: {
historyApiFallback: true,
contentBase: './'
},
watch: true,
watchOptions: {
aggregateTimeout:300,
poll: 1000,
ignored: /node_modules/
}
};
Found my problem - it lived in server.js.
The top answer on this question helped: What's the correct way to serve production react bundle.js built by webpack?
Needed to replace:
app.get(['/', '/bom', '/items', '/products', '/segmentation'], function (req, res) {
res.sendFile('index.html', {root: __dirname});
});
with:
app.get('*',function(req,res) {
res.sendFile(path.resolve(__dirname,'public/index.html'));
});
And that fixed my localhost render issue.

Webpack: Include vendor in only one module

I try to migrate one of my project building from browserify to webpack. It's AngularJS#1.7 project and I have multiple bundles: core with AngularJS and its dependenciy imports and other specific lazy-loading modules with its specific dependencies. So I have multiple entry points but I only load core.js script in index.html. Another modules resolve while routing by my resolver.
One of the lazy-loading modules imports AngularJS and it leads to duplicate code and WARNING: Tried to load AngularJS more than once. I want to Webpack check if modules were imported in core and load them from it.
I made it work but need to import one extra file common-vendors.js in index.html.
My config:
export default {
context: path.resolve(__dirname, './src/app'),
//...
entry: {
'core': './core/core.module',
'back-office': './back-office/back-office.module',
'front-office-1': './front-office-2/front-office-2.module',
'front-office-2': './front-office-3/front-office-3.module'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'www')
},
mode: config.env,
optimization: {
splitChunks: {
cacheGroups: {
'common-vendors': {
test: /[\\/]node_modules[\\/]/,
name: 'common-vendors',
chunks: 'initial',
minChunks: 2
}
}
},
runtimeChunk: {name: 'core'},
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {mangle: false}
})
]
},
plugins: [
new CompressionPlugin()
]
}
If you know a better solution, feel free to comment.

webpack 4 react loadable is not spliting vendor base on chucking point

I am currently using webpack 4 with react loadable to create chunks.
It actually chunks depends on the break point. However, vendor size remains same. React loadable is not supporting webpack 4 yet ? or I am missing some setup ?
css actually seems to splited into the chunk, though
{
output: {
path: 'tothe path',
publicPath: `/publicPath/`,
filename: '[name] + '.js',
chunkFilename: '[name]',
},
resolve: {
extensions: ['.js', '.json', '.css'],
alias: aliases
},
stats: {
warnings: false,
children: false,
},
optimization: {
splitChunks: {
chunks: "all",
name: true,
cacheGroups: {
common: {
name: "vendor" + ".js",
test: /[\\/]node_modules[\\/]/,
chunks: "all",
enforce: true,
reuseExistingChunk: false,
},
}
}
}
}
React-loadable doesn't work well with Webpack 4 yet,
take a look at this pull request.
There's a fork of react-loadable (by the author of PR),
but it didn't work for me either. I had a problem that some components wrapped in Loadable won't load.
#Bohdan Other
I also ran into this problem.
I found that the components can't load all import style. If I remove the style, the component will load normally.
I move all the styles to the entry file as a workaround.

Webpack AngularJS Sourcemaps issue

I've been struggling with getting my source-maps working in my app for quite a while. I have set
devtool: 'source-map',
in the webpack configuration, but they are still not available in the Chrome devtools.
I pushed a really simple app using my FE Stack hoping someone could identify the issue, whether it is with webpack, angular, or some other library. https://github.com/coreysnyder/Angular-Webpack3-Seed
Here are the versions I'm running:
{
CoreyApp: '1.0.0',
npm: '4.4.4',
ares: '1.10.1-DEV',
http_parser: '2.7.0',
icu: '57.1',
modules: '48',
node: '6.9.0',
openssl: '1.0.2j',
uv: '1.9.1',
v8: '5.1.281.84',
zlib: '1.2.8'
}
OSX 10.12.6
You will probably have to setup source map for different loaders individually.
For 'ng-annotate-loader' (Docs)
use: [{
loader: 'ng-annotate-loader',
options: {
add: true,
single_quotes: true ,
map: { inline: true, inFile: 'app.js', sourceRoot: __dirname + '/app' }}
}]
For less you can use documentation option like #ahmedelgabri suggested
use: [{
loader: "style-loader"
}, {
loader: "css-loader", options: {
sourceMap: true
}
}, {
loader: "less-loader", options: {
sourceMap: true
}
}]
Old post before OP github changes.
Other option is to add devtoolLineToLine: true in your output, if you want to use devtool: 'source-map'. But devtoolLineToLine is deprecated, so consider changing devtool to something else. devtool: 'source-map' demo image
output: isTest ? {} : {
devtoolLineToLine: true, // <= this line
sourceMapFilename: '[name].map',
path: __dirname + '/dist',
filename: '[name].bundle.js',
publicPath: publicPath
},
Alternatively you could use devtool: 'eval' or some variation of eval, like cheap-module-eval-source-map (similar behavior, but without file names) also works fine for me
I could fix your source maps for JS files, by adding the babel-loader. To do this, you need to install babel-loader:
npm i -D babel-loader#8.0.0-beta.0 #babel/core #babel/preset-env
and then extend your rule for .js
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'ng-annotate-loader',
options: { add: true, single_quotes: true }
},
{
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
]
}, [...]
]
Ready further details on babel-loader github repo
There is nothing wrong with the Webpack config here https://github.com/coreysnyder/Angular-Webpack3-Seed
here is a gif using your code & setting a breakpoint in view1 file
And here is why the text is blue
And I can see the source just fine
The main issue is the less-loader you need to pass the source-maps options for both, the less-loader & css-loader check the readme
{
test: /\.less$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'less-loader',
options: {
sourceMap: true,
},
},
],
},
After doing this you will be able to debug from the styles panel like this
If you want to edit directly the .less files the readme mentions a blog post that can help with this https://github.com/webpack-contrib/less-loader#source-maps
I hope this answers your question

Resources