Karma webpack - cannot handle css import in js - javascript

I am coding some learning project to implement TDD, webpack.
I use webpack 2 with the following config:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
//const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash');
process.noDeprecation = true;
module.exports = {
entry: './src/js/index.js',
devtool: 'source-map',
context: __dirname,
target: 'web',
stats: 'errors-only',
watch: true,
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].[chunkHash].js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.jsx?$/,
include: [
path.resolve(__dirname, 'src')
],
exclude: [
path.resolve(__dirname, 'node_modules')
],
loader: 'babel-loader',
options: {
presets: ['es2015']
},
},
{
test: /\.css$/,
/*use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})*/
use: [ 'style-loader', 'css-loader' ]
}
]
},
plugins: [
new WebpackMd5Hash(),
//new ExtractTextPlugin('[name].[contenthash].css'),
new HtmlWebpackPlugin({
template: 'src/index.html',
filename: 'index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
},
inject: true
}),
new webpack.optimize.UglifyJsPlugin()
],
devServer: {
contentBase: path.join(__dirname, "dist/"),
compress: true,
port: 8080
}
}
When I run simply webpack it compiles and works fine. But when I try to run karma with webpack preprocessor, it gives the following error:
Uncaught Error: Module parse failed: C:\Users\Javid\Desktop\projects\rejection\src\css\style.css Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
I use import '../css/style.css'; in my js file. Googled it a lot, didn't find a solution.
Solution
I used additionaly raw-loader to handle my css and changed my import to look like this: import css from 'raw-loader!../css/style.css';

Reference: https://angular.io/docs/ts/latest/guide/webpack.html
This site shows a good example of a project for development, test, and production builds. In particular to your question, it looks as if a loader is used to ignore the .css files when running karma.
Here is a sample of their files related to karma:
"karma.config.js":
module.exports = require('./config/karma.conf.js');
"karma.conf.js":
var webpackConfig = require('./webpack.test');
module.exports = function (config) {
var _config = {
basePath: '',
frameworks: ['jasmine'],
files: [
{pattern: './config/karma-test-shim.js', watched: false}
],
preprocessors: {
'./config/karma-test-shim.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
},
reporters: ['kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
singleRun: true
};
config.set(_config);
};
"webpack.test.js":
var webpack = require('webpack');
var helpers = require('./helpers');
module.exports = {
devtool: 'inline-source-map',
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
loaders: [
{
loader: 'awesome-typescript-loader',
options: { configFileName: helpers.root('src', 'tsconfig.json') }
} , 'angular2-template-loader'
]
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'null-loader'
},
{
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: 'null-loader'
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw-loader'
}
]
},
plugins: [
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
helpers.root('./src'), // location of your src
{} // a map of your routes
)
]
}

Related

css module not apply to react component after Webpack build

I'm currently working with the latest version of Webpack to build files from TSX and SCSS files, so my issue is after building files to JS and CSS modules. all of the styles don't apply to any react components,
you can see my configure below
This is my SCSS file.
// Home.module.scss
.addgame {
background-color: aqua;
}
My React file
import React from 'react';
const styles = require('./Home.module.scss');
export default function HomePage() {
return (
<div className={styles.addgame}>HomePage</div>
);
}
I have 2 files of Webpack
//Webpack.config.js
// const webpack = require('webpack');
const { merge } = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
devtool: 'source-map',
plugins: [
new HtmlWebpackPlugin({
hash: true,
template: './src/index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}),
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
chunkFilename: '[id].[contenthash].css',
}),
],
optimization: {
moduleIds: 'deterministic',
runtimeChunk: true,
}
});
this is common Webpack
//webpack.common.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
context: process.cwd(),
entry: {
index: './src/index.tsx',
},
plugins: [new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }), new WebpackManifestPlugin()],
module: {
rules: [
{
test: /\.ts(x?)$/,
use: ['babel-loader', 'ts-loader'],
exclude: /node_modules/,
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
},
],
},
{
test: /\.s[ac]ss$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
modules: {
namedExport: true,
},
},
},
{
loader: 'css-loader',
options: {
modules: true,
// Run `postcss-loader` on each CSS `#import`, do not forget that `sass-loader` compile non CSS `#import`'s into a single file
// If you need run `sass-loader` and `postcss-loader` on each CSS `#import` please set it to `2`
importLoaders: 2,
},
},
'postcss-loader',
'sass-loader',
],
},
{
// asset
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
{
// asset
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js', 'scss'],
},
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, '../build'),
pathinfo: false,
publicPath: '/',
},
};
//postcss configure
module.exports = {
plugins: [
"postcss-preset-env",
"postcss-modules"
]
}
///babel
{
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3
}
],
["#babel/preset-typescript"],
["#babel/preset-flow"],
["#babel/preset-react"]
],
"plugins": [
["#babel/plugin-transform-flow-strip-types"],
["const-enum"],
["#babel/plugin-transform-typescript"],
["#babel/plugin-syntax-dynamic-import"],
["#loadable/babel-plugin"]
]
}

Optimizing webpack build time

I have a problem compiling a project after saving a change in the files; the compilation time of the files takes 2 or more minutes.
To fix the problem, I took the following steps:
1.In babel-loader from the documentation in the option object for properties cacheDirectory set to true, cacheComprassion to false
2. In the ts-loader from the documentation in the option object for the properties transpileOnly and happyPackMode set to true
3.dev-tool disabled for better performance
4. ForkTsCheckerWebpackPlugin connected to check types in typescript
5. Code splitting customized
Webpack config file
const path = require('path');
const ESLintPlugin = require('eslint-webpack-plugin');
const webpack = require('webpack');
// eslint-disable-next-line import/no-extraneous-dependencies
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
entry: [
path.resolve(__dirname, 'src/index.tsx'),
],
mode: 'development',
module: {
rules: [
{ parser: { requireEnsure: false } },
{
test: /\.(ts|tsx)$/,
exclude: /(node_modules)/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true,
cacheCompression: false,
},
},
{
loader: 'ts-loader', options: {
transpileOnly: true,
happyPackMode: true
},
},
],
},
{
test: /\.scss$/,
use: [
{
// creates style nodes from JS strings
loader: 'style-loader',
},
{
// translates CSS into CommonJS
loader: 'css-loader',
},
{
// compiles Sass to CSS
loader: 'sass-loader',
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
// eslint-disable-next-line global-require
require('autoprefixer'),
],
},
},
],
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'less-loader'],
}),
},
{
test: /\.css$/,
use: [
{
// creates style nodes from JS strings
loader: 'style-loader',
},
{
// translates CSS into CommonJS
loader: 'css-loader',
},
],
},
{
test: /\.svg/,
use: {
loader: 'svg-url-loader',
},
},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
],
},
// devtool: 'source-map',
optimization: {
runtimeChunk: {
name: 'app',
},
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
minimize: true,
},
resolve: { extensions: ['*', '.js', '.jsx', '.ts', '.tsx', 'scss'], modules: ['node_modules'] },
output: {
// path: `${__dirname}/dist`,
// filename: 'app.js',
publicPath: 'http://localhost:3000/hmr/',
chunkFilename: '[id].js?v=[chunkhash]',
},
devServer: {
stats: {
// assets: true,
// cachedAssets: true,
// performance: true,
// entrypoints: true,
// chunkGroups: true,
// chunks: true,
// chunkModules: true,
// show modules contained in each chunk
// chunkOrigins: true,
// show the origin of a chunk (why was this chunk created)
// chunkRelations: true,
// show relations to other chunks (parents, children, sibilings)
// dependentModules: true,
},
disableHostCheck: true,
host: '127.0.0.1',
port: 3000,
publicPath: '/hmr/',
filename: 'app.js',
// hot: true,
// hotOnly: true,
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new ForkTsCheckerWebpackPlugin({
typescript: {
diagnosticOptions: {
semantic: true,
syntactic: true,
},
},
async: true,
}),
new ESLintPlugin({
eslintPath: 'eslint',
fix: true,
quiet: true,
extensions: ['ts', 'tsx'],
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
],
};
Please tell me how you can reduce the compilation time of files in the project after saving the files?
Solved the issue. The problem turned out to be in the eslint-loader-webpack plugin. If you install the old version of eslint-loader, then everything works fine.
How to solve the issue of the eslint-loader-webpack plugin slow?

Module not found: Error: Can't resolve 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true' when using webpack-hot-middleware

I am using webpack-hot-middleware for hot module replacement for javascript ui scripts in an express app. Whenever I start the server, I get this error:
Module not found: Error: Can't resolve 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true'.
Here is my webpack config, which I compile in the webserver:
const path = require('path');
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: [ path.join(__dirname, 'ui/lib/utilities/index.js') , 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true' ],
output: {
path: path.join(__dirname, 'ui/dist'),
filename: '[name].js',
publicPath: 'http://localhost:3000'
},
resolve: {
extensions: [
'.js',
],
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/, // exclude any and all files in the node_modules folder
include: path.resolve(__dirname, 'scripts'),
use: [
{
loader: 'babel-loader',
options: {
presets: ['env', 'es2015'],
plugins: [
// OccurrenceOrderPlugin is needed for webpack 1.x only
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
// Use NoErrorsPlugin for webpack 1.x
new webpack.NoEmitOnErrorsPlugin()
],
camelcase: true,
emitErrors: false,
failOnHint: false,
},
},
{ loader: 'style-loader' },
{ loader: 'css-loader' },
],
},
],
},
};
And here's the compilation in the server code:
web.use(webpackDevMiddleware(compiler, {
noInfo: true,
publicPath: webpackConfig.output.publicPath,
writeToDisk: true,
hot: true
}));
web.use(require("webpack-hot-middleware")(compiler, {
log: console.log, path: '/__webpack_hmr', heartbeat: 10 * 1000
}));

Extract text Webpack plugin compile error

I'm using "webpack": "^3.1.0" and "extract-text-webpack-plugin": "^1.0.1"
Trying to compile sass and I get the following error: Error: "extract-text-webpack-plugin" loader is used without the corresponding plugin, refer to https://github.com/webpack/extract-text-webpack-plugin for the usage example
I have used this as per the documents provided - don't understand why I'm getting webpack build errors.
Here is my webpack file:
const debug = process.env.NODE_ENV !== "production";
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
context: path.join(__dirname, "src"),
devtool: debug ? "inline-sourcemap" : null,
entry: ['./js/client.js', './styles/base.scss'],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-0'],
plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy'],
}
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
//resolve-url-loader may be chained before sass-loader if necessary
use: ['css-loader', 'sass-loader']
})
}
]
},
output: {
path: __dirname + "/src/",
filename: "client.min.js"
},
plugins: debug ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
new ExtractTextPlugin('main.css')
],
};
You need to include something to tell where webpack to look, for example:
{
test: /(\.css|\.scss|\.sass)$/,
include: path.join(__dirname, "../src"), // Include or exclude node modules
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader", "sass-loader"],
}),
},
Here is my webpack.config.babel.js file I hope this will helps you.
import HtmlWebpackPlugin from 'html-webpack-plugin';
import ExtractTextPlugin,{extract} from 'extract-text-webpack-plugin';
import {resolve,join} from 'path';
// import webpack from 'webpack';
// var isProd = process.env.NODE_ENV === 'production'; //return true or false
// var cssDev = [ "style-loader", "css-loader", "sass-loader" ];
// var cssProd = extract({
// fallback: "style-loader",
// use: [ "css-loader", "sass-loader"],
// publicPath:'/dist'
// });
// var cssConf = isProd ? cssProd : cssDev;
module.exports = {
entry: {
app:'./src/app.js',
},
output: {
path: join(__dirname, "dist"),
filename : '[name].bundle.js'
},
module: {
rules:[
{
test: /\.scss$/,
exclude: /node_modules/,
use: extract({
fallback: "style-loader",
use: [ "css-loader", "sass-loader"],
publicPath:'/dist'
})
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.(png|jpg|gif)$/,
use:"file-loader",
}
]
},
devServer:{
contentBase: join(__dirname, "dist"),
compress: true,
port: 9000,
stats:'errors-only',
},
plugins: [
new HtmlWebpackPlugin({
title: 'Webpack starter project',
template: './src/index.html',
hash:true,
excludeChunks: ['contact'],
minify:{
collapseWhitespace: true,
minifyCSS: true,
minifyJS:true,
}
}),
new ExtractTextPlugin({
filename: "app.css",
// disable: !isProd,
disable: false,
allChunks: true
}),
// new webpack.HotModuleReplacementPlugin(),
// new webpack.NamedModulesPlugin(),
]
}
you have to change the version of Extract Text Plugin
Instead of new ExtractTextPlugin('main.css') use new
ExtractTextPlugin({ filename: "main.css"})

Karma fail - Module parse failed

Trying to use Mocha frameworks with Karma Runner on reactJs application.
some reason I have a following error messages :
Module parse failed: C:\Dev\marvel-memory-card-v2\src\index.scss Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
Uncaught Error: Cannot find module "./index.scss" at tests.webpack.js:22214
Since everything is pretty new to me. No idea How to solve this issue.
Here is my webpack.config files :
"use strict";
var webpack = require('webpack');
var path = require('path');
var loaders = require('./webpack.loaders');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var DashboardPlugin = require('webpack-dashboard/plugin');
const HOST = process.env.HOST || "127.0.0.1";
const PORT = process.env.PORT || "8888";
// global css
loaders.push({
test: /\.css$/,
exclude: /[\/\\]src[\/\\]/,
loaders: [
'style?sourceMap',
'css'
]
});
// local scss modules
loaders.push({
test: /\.scss$/,
exclude: /[\/\\](node_modules|bower_components|public\/)[\/\\]/,
loaders: [
'style?sourceMap',
'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]&sourceMap',
'postcss',
'sass'
]
});
// local css modules
loaders.push({
test: /\.css$/,
exclude: /[\/\\](node_modules|bower_components|public\/)[\/\\]/,
loaders: [
'style?sourceMap',
'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]&sourceMap'
]
});
module.exports = {
entry: [
'react-hot-loader/patch',
'./src/index.jsx' // your app's entry point
],
devtool: process.env.WEBPACK_DEVTOOL || 'eval-source-map',
output: {
publicPath: '/',
path: path.join(__dirname, 'public'),
filename: 'bundle.js'
},
resolve: {
extensions: ['', '.js', '.jsx']
},
module: {
loaders
},
devServer: {
contentBase: "./public",
// do not print bundle build stats
noInfo: true,
// enable HMR
hot: true,
// embed the webpack-dev-server runtime into the bundle
inline: true,
// serve index.html in place of 404 responses to allow HTML5 history
historyApiFallback: true,
port: PORT,
host: HOST
},
plugins: [
new webpack.NoErrorsPlugin(),
new webpack.HotModuleReplacementPlugin(),
new DashboardPlugin(),
new HtmlWebpackPlugin({
template: './src/template.html'
}),
]
};
and karma.conf file
var webpack = require('webpack');
module.exports = function (config) {
config.set({
browsers: ['Chrome'],
singleRun: true,
frameworks: ['mocha'],
files: [
'tests.webpack.js'
],
preprocessors: {
'tests.webpack.js': ['webpack']
},
reporters: ['dots'],
webpack: {
module: {
loaders: [
{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader'}
]
},
watch: true
},
webpackServer: {
noInfo: true
}
});
};
Any idea to solve my issue ? Please let me know.
Huge Thanks
Try to add this line to your karma configuration:
basePath : __dirname + '/',
and this is the scss loader for webpack:
{
test: /\.scss$/,
exclude: /[\/\\](node_modules|bower_components|public\/)[\/\\]/,
loaders: [
'style?sourceMap',
'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]&sourceMap',
'postcss',
'sass'
]
}
So your file should look like this:
module.exports = function (config) {
config.set({
basePath : __dirname + '/',
browsers: ['Chrome'],
singleRun: true,
frameworks: ['mocha'],
files: [
'tests.webpack.js'
],
preprocessors: {
'tests.webpack.js': ['webpack']
},
reporters: ['dots'],
webpack: {
module: {
loaders: [
{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader'},
{
test: /\.scss$/,
exclude: /[\/\\](node_modules|bower_components|public\/)[\/\\]/,
loaders: [
'style?sourceMap',
'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]&sourceMap',
'postcss',
'sass'
]
}
]
},
watch: true
},
webpackServer: {
noInfo: true
}
});
};

Categories