Webpack AngularJS Sourcemaps issue - angularjs

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

Related

Why Webpack parse less style used by a library in the node_modules and how to prevent that

I'm using the Antd react component library, and our project got bigger over time, so we decided to create a costume Webpack workflow to optimize the build time. the problem is Webpack parse Antd components and try to resolve .less file which is used by Antd and I don't use it in my project at all, and I don't customize Antd theme neither.
How should I config Webpack to avoid parsing Antd library and anything in node_modules?
this is my webpack.dev.config.ts file:
import path from "path";
import { Configuration } from "webpack";
import HtmlWebpackPlugin from "html-webpack-plugin";
const config: Configuration = {
mode: "development",
devtool: "inline-source-map",
entry: "./src/index.tsx",
target: ["browserslist"],
output: {
publicPath: "/",
},
module: {
rules: [
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
exclude: path.resolve(__dirname, "node_modules"),
use: [
{
loader: "ts-loader",
options: {
transpileOnly: true,
},
},
],
},
{
test: /\.css$/i,
exclude: path.resolve(__dirname, "node_modules"),
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: true,
importLoaders: 1,
},
},
{
loader: "postcss-loader",
},
],
},
{
test: /\.svg$/,
exclude: path.resolve(__dirname, "node_modules"),
use: [
{
loader: "svg-url-loader",
options: {
limit: 10000,
},
},
],
},
],
},
resolve: {
modules: ["node_modules"],
extensions: [
".js",
".ts",
".tsx",
".json",
".jsx",
],
},
plugins: [
new HtmlWebpackPlugin({
template: "public/index.html",
}),
],
devServer: {
static: path.join(__dirname, "build"),
historyApiFallback: true,
hot: true,
port: 4000,
open: true,
},
};
export default config;
As far as I can tell from the Webpack config above, you're not parsing anything from node_modules. The only issue I can see might be that this resolved path is incorrect (depends on where this configuration resides in relation to node_modules):
exclude: path.resolve(__dirname, "node_modules")
At which point, all node_modules might be transpiled by ts-loader (and the other loaders) if the path is incorrect.
On that note, since you haven't set up a less loader rule in Webpack to handle antd less files, the only thing you'll be importing from the antd library would be the unstyled JS files.
For example, if you visit the Your First Example within the antd documentation, you'll only see styled antd components when you import "antd/dist/antd.css";:
Otherwise, when you comment out the antd CSS import, the antd components become unstyled:
If you don't see the same result as above with your Webpack configuration, then it's likely that your exclude paths are incorrect or you have an import to node_modules within your code-base that points to a style directory within an antd component -- as is, none of the files within the root directory of a date-picker component (shown below) have an import/require statement that points to the style directory and, as a result, should be unstyled when imported within your code-base:

mini-css-extract plugin with postcss throws this.getOptions is not a function

I'm trying to set up a tailwind css for my personal project. It's a react SSR application. I'm having an issue with postcss setup under the webpack configuration. It throws the same error on every *.css file (even on the empty ones).
It looks like it can't resolve the configuration file or default options? Tried different configurations, but no effect. Initially, I thought that it could be something with my css files, but they all valid and compile if I remove postcss plugin
webpack config
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const paths = require('./paths');
module.exports = {
entry: {
index: path.resolve(paths.projectSrc, 'index.js'),
},
resolve: {
alias: {
'#src': paths.projectSrc,
},
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true },
},
],
exclude: /node_modules/,
},
{
exclude: /node_modules/,
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: path.resolve(__dirname, './client-build/css/'),
},
},
{
loader: 'css-loader',
options: { importLoaders: 1 },
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
config: path.resolve(__dirname, 'postcss.config.js'),
},
},
},
],
},
{
test: /\.(woff2?|ttf|otf|eot|png|jpg|svg|gif)$/,
exclude: /node_modules/,
loader: 'file-loader',
options: {
name: './assets/[name].[ext]',
},
},
],
},
plugins: [
new ESLintPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(paths.public, 'index.html'),
filename: 'index.html',
}),
new MiniCssExtractPlugin({
filename: '[name].bundle.css',
chunkFilename: '[id].css',
}),
new CopyWebpackPlugin({
patterns: [{ from: path.resolve(paths.public, 'assets'), to: 'assets' }],
}),
],
devtool: 'inline-source-map',
};
postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
console output
This is caused by a breaking change in v5.0.0 of postcss-loader where support for version 4 of webpack was dropped.
README which states:
Changelog
All notable changes to this project will be documented in this file. See standard-version for commit guidelines.
5.0.0 (2021-02-02)
⚠ BREAKING CHANGES
minimum supported webpack version is 5
How to fix it
You will need to downgrade postcss-loader to v4.2.
Side Note for Angular Projects
In case this helps other readers: You may not just see this in React projects. I found this issue after upgrading an Angular 8 project to Angular 11.
While I can't help with React projects, this Angular hint may also be of use anyways.
If you are on an Angular project and you've already tried to fix this issue by upgrading to v5 of webpack and then ran into dependency issues with libraries using v4 of webpack - You will want to follow these steps.
Downgrade postcss-loader to v4.2 as mentioned above.
Remove webpack v5 from package.json.
Delete package.lock.json.
Delete node_modules directory.
Run npm install.
Run ng serve or ng build.
Tell the boss you fixed it.
After this, you should be good to go with tailwindcss and Angular.

Webpack doesn't create right paths for images in production css file

To add images into the project i'm using content: url() css property inside sass file and specify relative path to src folder e.g. content: url('/images/right-arrow.svg');.
The problem is that in production build i need to get rid of the first slash to have such path ('images/right-arrow.svg') inside of a bundled css file.
The only way i could get desired behaviour is to use url: false option for css-loader, and writing path without slash in sass file: content: url('/images/right-arrow.svg'), but such option don't add necessary file from node_modules e.g. fonts and images.
Webpack Config:
return {
entry: ['babel-polyfill', './src/app.js'],
output: {
path: path.join(__dirname, 'public/'),
filename: '[name].[hash].js',
},
mode: isProduction || 'development',
module: {
rules: [
{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
},
{
test: /\.s?css$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
{
loader: 'css-loader',
options: {
url: true
}
},
'sass-loader'
]
},
{
test: /\.(svg|gif|png)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images'
}
}
},
{
test: /\.(otf|woff2|ttf|eot|woff)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
}
]
}
What am i missing in webpack config to achieve paths to work correcty?
Ok, I've solved the issue. I was using resolve-url-loader with no results, before #Ujin suggested to use it. After his comment I've clarified what resolve-url-loader does and cofigured it propertly to solve my issue. The main problem is that I've missed to read important paragraph of resolve-url-loader docs, which says:
source-maps required for loaders preceding resolve-url-loader (regardless of devtool).
Also I didn't use root option of resolve-url-loader plugin. So, webpack config for .scss files looks like this:
test: /\.s?css$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
{
loader: 'resolve-url-loader',
options: {
root: path.join(__dirname, 'src')
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
sourceMapContents: false
}
}
]
}
Check the documentation about problems with url(...).
It suggests using resolve-url-loader.
Also you can try to use copy-webpack-plugin

Load images in React using webpack loader

I am unable to display images within a React component. After many trials (attempted this, this, this, this, this, this, this and this) and only errors, I am requesting for help. I'm in the development build (not production build).
I still get this error:
Module parse failed: /project/src/images/net.png Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
Component
import thumbnail from '../images/net.png';
<img src={thumbnail}/>
Webpack config:
devtool: 'cheap-module-eval-source-map',
entry: [
'eventsource-polyfill',
'webpack-hot-middleware/client',
'./src/index'
],
target: 'web',
output: {
path: path.resolve(__dirname, 'dist'),
task `npm run build`.
publicPath: 'http://localhost:3000/',
filename: 'bundle.js'
},
devServer: {
contentBase: './src'
},
plugins: [new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin()],
module: {
rules: [
{
test: /\.js$/,
include: path.join(__dirname, 'src'),
loader: 'babel-loader'
},
{
test: /(\.css)$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { sourcemap: true }
}
]
},
{
test: /\.(svg|png|jpg|jpeg|gif)$/,
include: './src/images',
use: {
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
outputPath: paths.build
}
}
}
]
}
Directory Structure
Project
-- src
-----components
-----images
-----index.js
How can I display the image ?
Sample code here: githublink
See /src/components/home/HomePage.js
What can I do to see the image on the home page ?
Have you tried this webpack configuration
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
I am using url-loader instead.
{
test: /\.(png|jpg)$/,
use: {
loader: 'url-loader',
options: {
limit: 25000 // Max file size = 25kb
}
}
}
I am not sure. But, I think you should install it first as devDependencies e.g. yarn add -D url-loader.
test: /\.(jpe|jpg|woff|woff2|eot|ttf|svg)(\?.*$|$)/,
Try using this with your file-loader loader.
notice the (?.*$|$) instead of a plain $.
{
test: /.(png|jp(e*)g|svg|gif)$/,
use:[{
loader: 'url-loader?limit=8192'
}]
}
I loaded png with url-loader instead inside webpack. You need to rebuild webpack as well.

Webpack 2 extract text plugin entrypoints.length issues

I have an issue with upgrading to webpack 2 and the extract text plugin. I have the dev version (without this plugin) working and I cant see whats different. The error I get is
node_modules\webpack\lib\Chunk.js:62
return this.entrypoints.length > 0;
TypeError: Cannot read property 'length' of undefined
I have gulp running webpack 2 and this plugin for a single css file. This is the main part of my webpack config (happy to provide it all if needed):
...
modules: { rules :[ ... {
test: /\.scss/,
exclude: /node_modules/,
use: [
"style-loader?sourceMap",
{
loader: "css-loader",
options: {
minimize: true,
modules: true,
importLoaders: true,
localIdentName: "[path]___[name]__[local]___[hash:base64:5]",
},
},
{
loader: "postcss-loader",
options: { ...postCSSConfig },
},
{
loader: "sass-loader",
options: { includePaths: [path.join(process.cwd(), "src", "Styles", "Includes")] },
},
],
}, ]},
plugins: [
new ExtractTextPlugin({
filename: "[contenthash].css",
allChunks: true,
}), ...
Im using the following versions:
Webpack: 2.3.3
Extract text plugn: 2.0.1
Edit: Here is my entry point,
context: path.resolve(process.cwd(), "./src/"),
entry: [
"babel-polyfill",
"whatwg-fetch",
"Boot",
],
devtool: "eval",
resolve: {
modules: ["src", "node_modules"],
extensions: [".js", ".jsx"],
},
Any ideas would be great.
Thanks in advance.
According to docs, you also have to create proper rule for loading styles.
Please take a look at that, it's my rule. Please let me know if it helped you.
{
test: /\.(scss|css)$/,
exclude: /node_modules/
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader', 'sass-loader']
})
}
Anyway, yet I didn't manage to use ExtractTextPlugin with sourceMaps, so I can't give you solution to use this plugin with source maps.

Resources