Related
For example, my javascript file contains function that's only called when I press HTML button. As far as I know, Webpack will treat the function as a 'dead code' because it isn't used anywhere in javascript file and then dropped the code.
So, the question is how can I disable Webpack from dropping the dead code? (or any other way would also helpful)
For more information, I tried following this thread but still can't figure out how:
How to prevent unused code from being dropped during webpack build?
What I also already did was exporting everything inside index.js and import them in main.js along with other things like jquery and mathjs which then be compiled by Webpack. The output file has jquery, mathjs, and only console.log from main.js and general.js.
Even when I set the mode in development or none, the output file doesn't work at all.
// package.json
{
"private": true,
"devDependencies": {
"css-loader": "^6.7.3",
"css-minimizer-webpack-plugin": "^4.2.2",
"html-loader": "^4.2.0",
"html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "^2.7.2",
"purgecss-webpack-plugin": "^5.0.0",
"terser-webpack-plugin": "^5.3.6",
"uglify-js": "^3.17.4",
"uglifyjs-folder": "^3.2.0",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
},
"dependencies": {
"jquery": "^3.6.3",
"mathjs": "^11.5.0"
}
}
Here's my webpack.config.js (though I don't think there's problem here):
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = [
{
mode: 'production',
module: {
rules: [
{
test: /.html$/i,
loader: "html-loader",
},
{
test: /.s?css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
optimization: {
minimizer: [...,new CssMinimizerPlugin()]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.php'
}),
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
}),
],
},
]
Here's some part of the javascript file:
// main.js
import 'jquery';
import { evaluate } from 'mathjs';
console.log(evaluate('2+3'));
import js from './general.js';
// general.js
export let result;
export function clr() {
$('.input').text('0');
$('.result').text('0').removeClass('visible');
$('.input').addClass('highlight');
$('.result').removeClass('highlight');
return result = 0;
}
...
console.log('javascript loaded');
// output.js
// (...last part of the code, just to show that the javascript files are compiled successfully)
.......ImmutableDenseMatrix:Eb,Index:Ab,Spa:$b,Unit:Gb,SymbolNode:kN,FunctionNode:zN,Help:UN,Parser:GN}),FN.createProxy(hN),console.log("javascript loaded"),console.log($N("2+3"))})()})();
(I'm sorry if I can't explain it well. If there's something that I missing please let me know)
I have a main Stylesheet style.scss, which I imported in my main JavaScript file script.js:
import "./style.scss";
This works great, and I could build my website that way in dev mode. Now I wanted to try and use separate Stylesheet and import them in my main stylesheet with the #import rule, like so:
#import "./blocks/SCSS/test.scss" screen and (min-width: 600px);
But now I get this error message:
ERROR in ./dev/style.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./dev/style.scss)
Module build failed (from ./node_modules/css-loader/dist/cjs.js):
Error: Can't resolve './blocks/SCSS/test.scss' in 'D:\Art Files\Design\Eigene Projekte\WP Book Theme Dev\dev'
And I don't understand why it can't resolve it. I use modules for my JavaScript as well, which works great. But now with SCSS, it does not work at all.
I tried googling for a solution and checked out several open threads, none could help me.
Here are some I checked out on Stackoverflow:
Module build failed (from ./node_modules/postcss-loader/src/index.js)
Module build failed (from ./node_modules/css-loader/dist/cjs.js): CssSyntaxError
Module build failed (from ./node_modules/sass-loader/dist/cjs.js)
Webpack: getting this error: build failed (from ./node_modules/css-loader/dist/cjs.js):
My Node version was 12.18.3, where I had the error first. Now I updated my node to the LTS to 14.15.4, still the same error.
Here are my Webpack config files:
// webpack.common.js
const path = require("path");
module.exports = {
entry: "./dev/script.js",
module: {
rules: [
{
test: /\.html$/i,
use: ["html-loader"],
},
{
test: /\.(svg|png|jpg)$/i,
use: {
loader: "file-loader",
options: {
esModule: false,
name: "[name].[hash].[ext]",
outputPath: "assets/images",
},
},
},
],
},
};
// webpack.dev.js
const path = require("path");
const common = require("./webpack.common.js");
const { merge } = require("webpack-merge");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = merge(common, {
mode: "development",
plugins: [
new HtmlWebpackPlugin({
template: "./dev/post.html",
}),
],
module: {
rules: [
{
test: /\.scss$/i,
use: ["style-loader", "css-loader", "sass-loader"],
},
],
},
devServer: {
contentBase: "./dist",
},
output: {
filename: "script.dev.js",
path: path.resolve(__dirname, "dist"),
publicPath: "./",
},
});
Here are my webpack dependencies:
"devDependencies": {
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^5.0.1",
"file-loader": "^6.2.0",
"html-loader": "^1.3.2",
"html-webpack-plugin": "^4.5.0",
"mini-css-extract-plugin": "^1.3.3",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"sass": "^1.32.0",
"sass-loader": "^10.1.0",
"style-loader": "^2.0.0",
"terser-webpack-plugin": "^5.0.3",
"webpack": "^5.11.1",
"webpack-cli": "^4.3.0",
"webpack-dev-server": "^3.11.1",
"webpack-merge": "^5.7.3"
},
This is what I did to fix my problem. Amaresh already mentioned something, about what I might be missing, but that didn't help me out with my problem, as I was given no real explanation on why that would help.
In the end, I did install sass*, and since node-sass is deprecated, I didn't pay any mind to it.
The way I used #import was probably wrong. I was trying to do it the native CSS way (MDN), but SCSS might have been overwriting that. #import by SCSS is also deprecated by now and not recommended. When I rechecked the SCSS Website, I went to their guide on how to use SCSS, and they mentioned how I could use #use to import another stylesheet. What I learned was that I need to use Partials. I had to lead filenames with an underscore to create a namespace for that, and import it using the #use rule.
From their example:
// _base.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
// styles.scss
#use 'base';
.inverse {
background-color: base.$primary-color;
color: white;
}
* I don't know if the installation of sass actually helped or not. Since the package is dealing with JavaScript, which I have not done so in my file. But since the package is also mentioned in the sass-loader, I will keep it.
What is important to remember when using #use is how you handle the file in the new file.
// src/_list.scss
#mixin list{
ul {
display: flex;
flex-direction: row;
li {
text-align: center;
padding: 5px;
}
}
}
By only calling the URL, you have to specify the namespace and then what you want to use from that namespace.
// styles.scss
#use "src/list";
header {
#include list.list;
}
You can call a new namespace and give it a custom name.
// styles.scss
#use "src/list" as myList;
header {
#include myList.list;
}
Or you can call it and name it with an asterisk, making it available, without having to write the namespace when calling it.
// styles.scss
#use "src/list" as *;
header {
#include list;
}
For further reading, please check out their documentation on #use.
Check whether you have installed all these packages:
sass (https://www.npmjs.com/package/sass)
sass-loader (https://www.npmjs.com/package/sass-loader)
css-loader (https://www.npmjs.com/package/css-loader)
style-loader(https://www.npmjs.com/package/style-loader)
node-sass (https://www.npmjs.com/package/node-sass)
you might be missing node-sass
I'm encountering an error while trying to setup scss in a vue project using single-file components. I currently encounter this error when I try to use a <style lang="scss"> block, but otherwise my project works as expected.
ERROR in ./src/App.vue?vue&type=style&index=0&lang=scss& (./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/sass-loader/lib/loader.js??ref--4-2!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=0&lang=scss&)
Module build failed (from ./node_modules/sass-loader/lib/loader.js):
<template>
^
Invalid operator in attribute selector for object
in C:\Users\yanch\OneDrive\Desktop\virtualenvs\agg_site\client\src\App.vue (line 1, column 2)
# ./src/App.vue?vue&type=style&index=0&lang=scss& (./node_modules/vue-style-loader!./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/sass-loader/lib/loader.js??ref--4-2!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=0&lang=scss&) 4:14-279
# ./src/App.vue?vue&type=style&index=0&lang=scss&
# ./src/App.vue
# ./src/main.js
# multi (webpack)-dev-server/client?http://localhost:8080 ./src/main.js
I'm not an expert but this error makes me think that there is an issue with my vue-loader rules. It seems like it's trying to compile the template as a style block (though I could be wrong). This is my webpack config:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const path = require('path');
module.exports = {
entry: './src/main.js',
module: {
rules: [
{ test: /\.js$/, use: 'babel-loader'},
{ test: /\.vue$/, use: 'vue-loader'},
{ test: /\.css$/, use: ['vue-style-loader', 'css-loader']},
{ test: /\.(png|jpg|gif)$/, use: 'file-loader' },
{ test: /\.scss$/, use: ['vue-style-loader','css-loader', 'sass-loader']},
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
new VueLoaderPlugin(),
],
devServer: {
historyApiFallback: true,
},
resolve: {
alias: {
'#': path.resolve(__dirname, './src'),
'~': path.resolve(__dirname, './src/style'),
}
},
};
And I have these packages installed:
"devDependencies": {
"#babel/core": "^7.2.2",
"#babel/preset-env": "^7.3.1",
"axios": "^0.18.0",
"babel-loader": "^8.0.5",
"babel-plugin-root-import": "^6.1.0",
"css-loader": "^2.1.0",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"node-sass": "^4.12.0",
"path": "^0.12.7",
"rimraf": "^2.6.3",
"sass-loader": "^7.1.0",
"vue": "^2.6.10",
"vue-loader": "^15.7.0",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.6.10",
"vuex": "^3.1.0",
"webpack": "^4.29.3",
"webpack-cli": "^3.2.3",
"webpack-dev-server": "^3.1.14"
},
I followed the vue-loader setup instructions and I believe I have all the necessary loaders installed along with the proper rules, so I'm unsure why I'm getting this error. Any help would be appreciated.
**Edit - Added App.vue below:
<template>
<div id="app-container">
<NavBanner class="nav-banner"/>
<ProfileBanner/>
<router-view></router-view>
</div>
</template>
<script>
import ProfileBanner from '#/components/ProfileBanner.vue';
import NavBanner from '#/components/NavBanner.vue';
export default {
data() {
return {
message: 'Welcome to Leddit',
};
},
components: {
ProfileBanner,
NavBanner,
}
};
</script>
<style lang="scss">
#app-container {
font-family: 'Roboto', sans-serif;
color: blue;
height: 100%;
width: 100%;
}
.nav-banner {
height: 10%;
}
</style>
I recently upgraded from Webpack 3 to 4. It's now throwing an error:
Module parse failed: Unexpected character '#' You may need an
appropriate loader to handle this file type. | #import
'./scss/variables.scss'; | | * { # ./src/index.js 1:0-22
In my styles.scss file, I am doing the following:
#import 'scss/variables.scss';
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
In my index.js file, I am only doing the following:
import './style.scss';
In my webpack.dev.js, all I changed was an addition of mode: 'development':
const StyleLintPlugin = require('stylelint-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const Dotenv = require('dotenv-webpack');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'public/bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: ['babel-loader', 'eslint-loader']
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader'])
}
]
},
plugins: [
new StyleLintPlugin({
configFile: '.stylelintrc',
context: 'src',
files: '**/*.scss',
failOnError: false,
quiet: false,
syntax: 'scss'
}),
new ExtractTextPlugin('public/style.css'),
new Dotenv()
]
};
I don't know what change from Webpack 3 to 4 has caused this error.
The issue I'm having is very similar to the issue posted here: Webpack 4 Module parse failed: Unexpected character '#' (1:0)
I have been through all related stackoverflow questions and none of them helped.
Here are the relevant dependencies in my package.json:
"babel-loader": "^7.1.4",
"css-loader": "^0.28.11",
"eslint-loader": "^1.9.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"node-sass": "^4.9.0",
"sass-loader": "^6.0.7",
"style-loader": "^0.20.3",
"stylelint-webpack-plugin": "^0.10.5",
"uglifyjs-webpack-plugin": "^1.2.5",
"webpack": "^4.8.3",
"webpack-cli": "^2.1.4"
Here are the relevant scripts in my package.json file, for reference in the comments:
"scripts": {
"watch": "./node_modules/.bin/webpack --mode development --watch --progress",
"build": "./node_modules/.bin/webpack --mode production"
},
The problem was the script I was using to run Webpack did not specify the config file. This is what it should look like:
"scripts": {
"watch": "./node_modules/.bin/webpack --watch --config webpack.dev.js",
},
I believe this was generating the #import problem because it was not loading the css-loader as without specifying the config file like above, it uses a default Webpack development config which does not include the css-loader.
As I mentioned in a comment on your question there's an open issue with Webpack 4 compatibility: https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/701
A fix for now is to install the alpha version of the library. I've done a small setup just now to test this and it works with webpack 4.
Install the alpha version npm i -D extract-text-webpack-plugin#next --save. Then install css-loader, sass-loader and node-sass.
Then in the webpack config file:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
...
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: {
loader: 'babel-loader'
},
exclude: /node_modules/,
include: path.join(__dirname, 'src')
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader'])
}
]
},
plugins: [
new ExtractTextPlugin('bundle.css'),
]
This correctly worked for me, and also concatenated multiple scss files that were using #import statements.
In package.json it should look like
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"webpack": "^4.8.3"
Edit: Just as a side note, apparently mini-css-extract-plugin works fine with webpack 4.
This worked for me: Replace your webpack styling config to the below code
module: {
rules: [
{
test: /\.(css|sass|scss)$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
}
]
}
I hope this resolves your issue thanks
I am having difficulty in getting CSS loading using css-loader on my JSX files. I was following the example from:
https://christianalfoni.github.io/react-webpack-cookbook/Loading-CSS.html
This is my JSX
import React from 'react';
import ReactDOM from 'react-dom';
import styles from './styles.css';
class Hello extends React.Component {
render() {
return <div>Hello world!</div>
}
}
var el = document.getElementById('content')
var data = JSON.parse(el.getAttribute('data-attr'))
ReactDOM.render(<Hello data={data} />, el);`
This is my package.json
"devDependencies": {
"babel-core": "^6.3.26",
"babel-loader": "^6.2.0",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"css-loader": "^0.23.1",
"exports-loader": "~0.6.2",
"expose-loader": "~0.6.0",
"grunt": "^0.4.5",
"grunt-babel": "^6.0.0",
"grunt-cli": "^0.1.13",
"grunt-contrib-watch": "^0.6.1",
"grunt-webpack": "^1.0.11",
"history": "^1.17.0",
"imports-loader": "~0.6.3",
"jquery": "^2.1.4",
"lodash": "~3.0.0",
"react": "^0.14.5",
"react-dom": "^0.14.5",
"react-router": "^1.0.3",
"style-loader": "^0.13.0",
"webpack": "^1.12.9",
"webpack-dev-server": "^1.14.0"
},
"dependencies": {
"chunk-manifest-webpack-plugin": "0.0.1",
"grunt-react": "^0.12.3"
}
This is my Webpack.config.js
var path = require('path');
var webpack = require('webpack');
var config = module.exports = {
// the base path which will be used to resolve entry points
context: __dirname,
// the main entry point for our application's frontend JS
entry: './app/frontend/javascripts/entry.js',
stats: {
// Configure the console output
colors: true,
modules: true,
reasons: true
},
progress: true,
keepalive: true,
module: {
loaders: [
{
test: /\.js?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader', // 'babel-loader' is also a legal name to reference
query: { presets: ['es2015', 'react'] }
},
{ test: /\.css$/, loader: "style-loader!css-loader" }
]
},
output: {
// this is our app/assets/javascripts directory, which is part of the Sprockets pipeline
path: path.join(__dirname, 'app', 'assets', 'javascripts'),
// the filename of the compiled bundle, e.g. app/assets/javascripts/bundle.js
filename: 'bundle.js',
// if the webpack code-splitting feature is enabled, this is the path it'll use to download bundles
publicPath: '/assets',
devtoolModuleFilenameTemplate: '[resourcePath]',
devtoolFallbackModuleFilenameTemplate: '[resourcePath]?[hash]',
},
resolve: {
// tell webpack which extensions to auto search when it resolves modules. With this,
// you'll be able to do `require('./utils')` instead of `require('./utils.js')`
extensions: ['', '.js'],
// by default, webpack will search in `web_modules` and `node_modules`. Because we're using
// Bower, we want it to look in there too
modulesDirectories: [ 'node_modules', 'bower_components' ],
},
plugins: [
// we need this plugin to teach webpack how to find module entry points for bower files,
// as these may not have a package.json file
new webpack.ResolverPlugin([
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin('.bower.json', ['main'])
]),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
}),
//new webpack.optimize.CommonsChunkPlugin('common-bundle.js'),
//new webpack.optimize.CommonsChunkPlugin('public-bundle.js')
]
};
This is my styles.css
#div {
background-color: red;
}
The output I get from running my grunt task to run 'webpack' attached:
You can see where it says the build failed for the CSS.
cjs require fbjs/lib/mapObject [154] ./~/react/lib/ReactDOMFactories.js 18:16-45
[157] ./~/react/lib/onlyChild.js 1.21 kB {0} [built]
cjs require ./onlyChild [153] ./~/react/lib/ReactIsomorphic.js 24:16-38
[158] ./~/react/lib/deprecated.js 1.77 kB {0} [built]
cjs require ./deprecated [3] ./~/react/lib/React.js 19:17-40
[159] ./~/react-dom/index.js 63 bytes {0} [built]
cjs require react-dom [0] ./app/frontend/javascripts/entry.js 11:16-36
ERROR in ./app/frontend/javascripts/styles.css
Module parse failed: /Users/Booboo/Projects/Xeon/app/frontend/javascripts/styles.css Line 1: Unexpected token {
You may need an appropriate loader to handle this file type.
| div {
| background-color: red;
| }
# ./app/frontend/javascripts/entry.js 5:0-23
Warning: Task "webpack:dev" failed. Use --force to continue.
Aborted due to warnings.
Booboo$ grunt react && grunt webpack && grunt watch
I encounter this problem too.
But in my case, I found my loader was written as
{test: '/\.css$/', loader: 'style!css'}
which should be correctly written as
{test: /\.css$/, loader: 'style!css'}
note the '' around the /.css$/
I wise this would be helpful for you.
When you say
import styles from './styles.css';
you're trying to import a module that's not being exported as a module.
Try
import './styles.css';
instead to make it a simple file import.