Webpack Automatically import css from node modules - css

TL;DR: Is there any way to automatically scan or automatically import all stylesheets used by our web packages, from our node_modules folder?
I am working on a project that uses angularJS as its MVC framework, and we are currently in the process of migrating to use webpack. I currently wrote the following configuration:
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const bbProperties = require('./webpack.properties');
const appRoot = __dirname + "/../../..";
console.log('__dirname:', __dirname);
module.exports = {
entry: {
app: appRoot + bbProperties.app.entryScript,
login: appRoot + bbProperties.login.entryScript
},
output: {
path: appRoot + bbProperties.distFolder,
publicPath: "dist",
filename: "js/[name].bundle.js",
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2017']
}
},
{
test: /\.css$/,
//exclude: /node_modules/,
use: [
{loader: 'style-loader'},
{loader: 'css-loader', query: {importLoaders: 1}},
{loader: 'postcss-loader', query: {config: {path: __dirname+'/postcss.config.js'}}}
]
},
{
test: /\.(png|jpg|jpeg|gif)$/,
exclude: /node_modules/,
use: [
{
loader: 'file-loader',
options: {
name:'[name].[ext]',
outputPath:"/assets/images/"
}
}
]
},
{
test: /\.(ttf|eot|woff|woff2|svg)($|\?.*$)/,
exclude: /node_modules/,
use: [
{
loader: 'file-loader',
options: {
name:'[name].[ext]',
outputPath:"/assets/fonts/"
}
}
]
},
]
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
moment: "moment"/*,
_: "lodash",
"window._": "lodash",
angular: "angular"*/
}),
//Creates an html file with all bundles injected as <script> tags
new HtmlWebpackPlugin({
chunks: ['app'],
filename: '../angular-app/menu/' + bbProperties.app.outputFile,
hash: "true", //cache busting
template: appRoot + bbProperties.app.location + "/" + bbProperties.app.inputFile
}),
//Second html bundle for login page
new HtmlWebpackPlugin({
chunks: ['login'],
filename: '../'+bbProperties.login.outputFile,
hash: "true", //cache busting
template: appRoot + bbProperties.login.location + "/" + bbProperties.login.inputFile
})
],
stats: {colors: true},
devtool: 'source-map',
node: {
fs: "empty"
}
};
As far as I understand, webpack will start creating a bundle from each entry file, adding any file it encounters in import statements recursively.
I also understand that I can require a package from my node_modules directory, and that in such a case webpack will search for a package.json file and import the file specified in the 'main' property of that file.
Lets say we are dependant on several packages, components and frameworks (for example: angular-ui-grid, angular-material etc...), I know I can manually import their CSS files using css loaders by importing them into my JS code.
Is there any way to automatically scan or automatically import all stylesheets used by those packages, from our node_modules folder?

Related

How to stop WebPack from including CSS file in the html even though it is already included in the produced js file

I am using WebPack to build a chrome extension. I import the css file in the popup.js file and it correctly styles my page but bundler also inserts the css file to the html which is unnecessary if I know correctly since it is injected to the output js file. Because the css file is included in the hmtl, I get a "Failed to load resource: net::ERR_FILE_NOT_FOUND". I want to know how to exclude the CSS file from the html and basically dont have the following line.
<link rel="stylesheet" href="popup-styles.css" />
This is my webpack.config.js file.
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
entry: {
popup: "./src/popup.js",
background: "./src/background.js",
content: "./src/content.js",
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"],
},
},
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/popup.html",
filename: "popup.html",
chunks: ["popup"],
}),
new CopyPlugin({
patterns: [{ from: "public" }],
}),
],
};

Compile CSS and JS in difference files / WEBPACK

For 2 days I have been trying to compile the js and css file to a separate file because now everything is together. Does anyone have any idea how this can be solved?
I would be very grateful for your help.
There is my code webpack.config.js
const path = require('path');
const webpack = require('webpack');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'src/dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
},
{
test: /\.scss$/,
use: [
"style-loader", // creates style nodes from JS strings
{
loader: "css-loader",
options: {
url: false
}
},
"sass-loader" // compiles Sass to CSS, using Node Sass by default
]
},
]
},
plugins: [
new BrowserSyncPlugin({
// browse to http://localhost:3000/ during development,
// ./public directory is being served
host: 'localhost',
port: 3000,
files: ['./src/*.html'],
server: { baseDir: ['src'] }
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
};
I think MiniCssExtractPlugin is what you are looking for.
It takes the output of css-loader and create .css bundles. It takes care of downloading them in the browser (by pushing a section of code in webpack runtime code), and also yeah, it minifies the .css :).
Simple usage:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
};
Yes you are right. Style-loader creates javascript snippets that later in runtime creates .css rules and push them to the browser global css scope.

Webpack build successfull but styles.css file style is not reflecting

I am developing a web application in angular 5.Now I have included webpack 4 in my application.But There is a problem all styles written in styles.css file are not reflecting in the build created from webpack.
Need solution for this problem.
Below is my webpack.common.js file which is used for loading diffrent types of files present in my application build always succeed but the styles.css code is not reflection on my site when it gets loaded in browser.But code written in components .scss file reflects properly i have searched a lot but did not find any solution for this issue why is is happening.
import styles from './styles.css';
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');
module.exports = {
entry: {
'polyfill': './src/polyfills.ts',
'vendor': './src/vendor.ts',
'app': './src/main.ts'
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
loader: ['awesome-typescript-loader','angular2-template-loader','angular-router-loader'
],
exclude:[/node_modules/]
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=assets/images/[name].[hash].[ext]'
},
{
test: /\.(css|scss)$/,
include: helpers.root('src', 'app'),
loaders: ['css-loader']
},
{
test: /\.js$/,
include: helpers.root('src', 'app'),
loader: 'babel-loader',
exclude:[/node_modules/],
query:{
presets:['es2015']
}
}
]
},
plugins: [
// Workaround for angular/angular#11580
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)#angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
),
new ExtractTextPlugin("src/styles.css"),
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
};
You should import your css stylesheet using #import from your main css/scss stylesheet.
Do NOT import a css file as a javascript module from the webpack config file. This has no sense.

unable to load css in react js

my all css files placed under src/assets/css/* and i am trying to import or load css file inside my component, i have tried to load css with below webpack configuration
Webpack file
{ test: /\.css$/, loader: "style-loader!css-loader" }
Component
import './../../assets/css/bootstrap.min.css';
Also tried to load css in index.html file like <link rel="stylesheet" href="/src/assets/css/bootstrap.min.css">
Also, is there a way if i have 5-6 css files by which i dont need to load all files in every component like if we can add in <head> tag
Here is my webpack.config file. I have used foundation instead of bootstrap but the webpack configuration is similar.
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: [
'script!jquery/dist/jquery.min.js',
'script!foundation-sites/dist/js/foundation.min.js',
'./app/app.jsx'
],
externals: {
jquery: 'jQuery'
},
plugins:[
new webpack.ProvidePlugin({
'$': 'jquery',
'jQuery': 'jquery'
})
],
output: {
path: __dirname,
filename: './public/bundle.js'
},
resolve: {
root: __dirname,
modulesDirectories: [
'node_modules',
'./app/components',
'./app/api'
],
alias: {
applicationStyles: 'app/styles/app.scss',
actions: 'app/actions/actions.jsx',
reducers: 'app/reducers/reducers.jsx',
configureStore: 'app/store/configureStore.jsx'
},
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [
{
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-0']
},
test:/\.jsx?$/,
exclude: /(node_modules|bower_components)/
}
]
},
sassLoader:{
includePaths: [
path.resolve(__dirname, './node_modules/foundation-sites/scss')
]
},
devtool: 'cheap-module-eval-source-map'
};
And yes you can bundle the css in one file with webpack and import it in the root component.
Check my github repo for more details- https://github.com/hmachaharywork/ReactTodo
Use Extract text plugin. Only import this plugin in your webpack.conf.js
const ExtractTextPlugin = require("extract-text-webpack-plugin");
and refactor your rule like:
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
Finally, push new instance in plugin list:
plugins: [
new ExtractTextPlugin("styles.css"),
]

Webpack: wrong absolute path in compiled CSS

I'm migrating an Angular 1 project in order to be able to deploy everything with Webpack.
So far, I managed to configure almost everything but I'm having issues trying to export the static assets (fonts and images mostly).
I've configured the ExtractTextPlugin as below
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader','css-loader', {allChunks: true}) }
and in the compiled CSS the paths are replaced but the resulting absolute path is wrong. In fact the resulting path is /assetsweb/assets/.. while I expect it to be /assets/...
I cannot understand where the /assetsweb part is coming from.
Here's the Webpack configuration I'm using
var webpack = require("webpack");
var path = require("path");
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
context: __dirname + "/src",
entry:{
web: "./web/wayonara.js",
mobile: "./mobile/wayonara.js"
},
output:{
path: __dirname + "/dist",
filename: "/[name]/bundle.js",
publicPath: "/assets"
},
plugins:[
new webpack.DefinePlugin({
ENV: JSON.stringify('dev')
}),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
EXIF: "exif-js",
"window.EXIF":"exif-js"
}),
new ExtractTextPlugin("/[name]/assets/css/bundle.css")
],
module:{
loaders: [
{
loader: "babel-loader",
test: /\.js?$/,
exclude: [/node_modules/, /bower_components/],
query: {
presets: ['es2015']
}
},
{ test: /\.html$/, loader: "html" },
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader','css-loader', {allChunks: true}) },
{
test: /\.(jpg|jpeg|png|svg)$/,
loader: "file-loader?name=[path][name].[ext]"
},
{
test: /\.(woff|woff2|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?/,
loader: 'file-loader?name=[path][name].[ext]'
}
]
}
};
Can you help me? Thanks in advance,
Best,
Maurizio

Resources