Jest-Vue-Quasar unit testing issue with ES modules - unit-testing

I'm have issues testing with Jest, I don't have much experience. My component is using my own ES Node Module, an it works fine in runtime, except when running the test., I'm using Vue3, Quasar and Jest.
I Tried different things such as mapping (moduleNameMapper) in the jest config file without success.
I get this error while running the test.
Cannot find module 'my-module' from 'src/Helpers.js'
In Helpers.js this is how is declared
import EventEmitter from 'events';
import { v4 as uuid } from 'uuid';
import { testMethod } from 'my-module';
This is my jest.config.js
const esModules = ['quasar/lang', 'lodash-es'].join('|');
/* eslint-env node */
module.exports = {
globals: {
__DEV__: true,
// TODO: Remove if resolved natively
// See https://github.com/vuejs/vue-jest/issues/175
'vue-jest': {
pug: { doctype: 'html' },
},
},
// noStackTrace: true,
// bail: true,
// cache: false,
verbose: true,
// watch: true,
collectCoverage: true,
reporters: [
'default',
[ 'jest-junit', {
outputDirectory: '<rootDir>/',
outputName: 'junit.xml',
} ]
],
coverageReporters: [
"json", "lcov", "text", "clover", "cobertura"
],
coverageDirectory: '<rootDir>/coverage',
collectCoverageFrom: [
'<rootDir>/src/**/*.vue',
//'<rootDir>/src/**/*.js',
'<rootDir>/src/**/*.ts',
//'<rootDir>/src/**/*.jsx',
//'<rootDir>/src/**/*.tsx',
],
coveragePathIgnorePatterns: ['/node_modules/', '.d.ts$'],
coverageThreshold: {
global: {
// branches: 50,
// functions: 40,
// lines: 50,
// statements: 50
},
},
testMatch: [
// Matches tests in any subfolder of 'src' or into 'test/jest/__tests__'
// Matches all files with extension 'js', 'jsx', 'ts' and 'tsx'
'<rootDir>/test/jest/__tests__/**/*.(spec|test).+(ts|js)?(x)',
'<rootDir>/src/**/*.jest.(spec|test).+(ts|js)?(x)',
],
// Extension-less imports of components are resolved to .ts files by TS,
// grating correct type-checking in test files.
// Being 'vue' the first moduleFileExtension option, the very same imports
// will be resolved to .vue files by Jest, if both .vue and .ts files are
// in the same folder.
// This guarantee a great dev experience both for testing and type-checking.
// See https://github.com/vuejs/vue-jest/issues/188#issuecomment-620750728
moduleFileExtensions: ['vue', 'js', 'jsx', 'json', 'ts', 'tsx'],
moduleNameMapper: {
'^~/(.*)$': '<rootDir>/$1',
'^src/(.*)$': '<rootDir>/src/$1',
'^app/(.*)$': '<rootDir>/$1',
'^components/(.*)$': '<rootDir>/src/components/$1',
'^layouts/(.*)$': '<rootDir>/src/layouts/$1',
'^pages/(.*)$': '<rootDir>/src/pages/$1',
'^assets/(.*)$': '<rootDir>/src/assets/$1',
'^boot/(.*)$': '<rootDir>/src/boot/$1',
'.*css$': '#quasar/quasar-app-extension-testing-unit-jest/stub.css',
},
transform: {
// See https://jestjs.io/docs/en/configuration.html#transformignorepatterns-array-string
[`^(${esModules}).+\\.js$`]: 'babel-jest',
'^.+\\.(ts|js|html)$': 'ts-jest',
// vue-jest uses find-babel-file, which searches by this order:
// (async) .babelrc, .babelrc.js, package.json, babel.config.js
// (sync) .babelrc, .babelrc.js, babel.config.js, package.json
// https://github.com/tleunen/find-babel-config/issues/33
'.*\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
'jest-transform-stub',
},
transformIgnorePatterns: [`<rootDir>/node_modules/(?!(${esModules}))`],
snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],
};
.babelrc
{
"plugins": ["#babel/plugin-syntax-dynamic-import"],
"env": {
"test": {
"plugins": ["dynamic-import-node"],
"presets": [
[
"#babel/preset-env",
{
"modules": "commonjs",
"targets": {
"node": "current"
}
}
]
]
}
}
}

Related

Webpack - vue, babel, stylus, pug config issues

My project has the following structure:
two types of components, vue and folder with pug/js/styl;
index.pug is the main file that is to be index.html and index.pug extends layout and includes other pug, like head.pug that has the main.js script with imports of other required scripts. index.pug may also include a div container for main .vue component just like other .pug and .vue files are to be populated with either .vue or .pug components.
-index.pug <= layout,head .pug, main.vue, main.js, main.styl
-- .pug, .js, .styl folder-components
-- .vue components
I can not configure webpack properly to have index.html, error.html, /scripts/bundle.js, /styles/main.css
static-dist/index.html is empty or filled with JS code. So it cannot properly compile .pug and there is a mess with other parts related to vue, styl, pug. How to fix that all?
//const webpack = require('webpack');
const path = require('path');
const PugPlugin = require('pug-plugin');
const { VueLoaderPlugin, default: loader } = require('vue-loader')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const threadLoader = require('thread-loader');
const autoprefixer = require('autoprefixer-stylus')
const devMode = process.env.NODE_ENV !== "production";
const PATHS = {
dist: path.resolve(__dirname, 'client-dist'),
};
threadLoader.warmup(
{
// pool options, like passed to loader options. must match loader options to boot the correct pool
},
[ // modules to load. can be any module, i. e.
'babel-loader',
'stylus-loader',
]
);
const config = {
entry: {
// The Pug file is the entry point for all scripts and styles. Source scripts and styles must be specified directly in Pug.
//error: './views/error.pug', // output to client-dist/index.html
index: './views/index.pug',
//script: path.join(__dirname + '/scripts/scripts.js'),
//'pages/page': './views/index.pug',
},
output: {
path: path.resolve('../client-dist'), //path.join(`${__dirname}`, `/../client-dist`),
filename: `scripts/bundle-[name].[contenthash:8].js`,
publicPath: '/' ,// public URL of the output directory when referenced in a browser
compareBeforeEmit: true, // true: will not write output file when file already exists on disk with the same content.
clean: true,
},
resolve: {
extensions: [".js", ".vue", ".css", "styl", "pug", "html"],
},
mode: 'development',
devtool: (devMode ? '#source-map' : false),
//devtool: 'eval-cheap-module-source-map',
cache: true,
module: {
rules: [
{
test: /\scripts.js$/,
exclude: file => ( /(node_modules|env_sr)/.test(file) && !/\.vue\.js/.test(file) ),
use: [
{
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env'],
plugins: ['#babel/plugin-transform-runtime'],
cacheDirectory: true,
}
},
{
loader: 'thread-loader',
options: {
workers: 2,
}
},
{
loader: "source-map-loader",
//enforce: "pre"
},
]
},
/*{ loader: "style-loader", // creates style nodes from JS strings },
{ loader: "css-loader", // translates CSS into CommonJS
options: { sourceMap: true, }, },*/
{
test: /\.css$/i,
use: [ MiniCssExtractPlugin.loader, "vue-style-loader", "css-loader"], //, "stylus-loader"
},
{
test: /\.vue$/i,
use: ["vue-loader"]
},
{
test: /\.vue\.(styl)$/,///\.vue$/i,
sideEffects: true,
//loader: 'vue-loader',
use: ["vue-style-loader", "css-loader", {//"vue-loader",
loader: 'stylus-loader', options: {
stylusOptions: {
includeCSS: false,
resolveURL: true,
lineNumbers: false,
hoistAtrules: true,
compress: true,
sourceMap: true,
outputPath: "/styles/",
publicPath: "/styles/"
}
},
}, //autoprefixer(),z
], //, "stylus-loader"
},
{
test: /\.styl(us)?$/,
exclude: /node_modules/,
sideEffects: true,
use:
[
{ loader: 'resolve-url-loader' },
MiniCssExtractPlugin.loader,
//{ loader: 'vue-style-loader' },
{ loader: 'css-loader' },
//{ loader: 'resolve-url-loader' },
{
loader: 'stylus-loader',
options: {
stylusOptions: {
use: ["nib" /* , autoprefixer() */],
include: [path.join(__dirname, "styles/")],
import: ["nib", path.join(__dirname, "styles/helpers/*")],
define: [
["$development", process.env.NODE_ENV === "development"],
["$production", process.env.NODE_ENV === "production"],
],
includeCSS: false,
resolveURL: true,
lineNumbers: true,
hoistAtrules: true,
compress: true,
sourceMap: true,
outputPath: "/styles/",
publicPath: "/styles/"
}
},
}, autoprefixer(),
/*{ loader: "style-loader", }, { loader: "css-loader", }, { loader: "stylus-loader", }, */
] /* vue-style-loader', 'stylus-loader'], options: { stylusOptions: {} } */
},
{
test: /\.pug$/i,
exclude: /node_modules/,
loader: 'vue-pug-loader',//PugPlugin.loader, // PugPlugin already contain the pug-loader //'vue-pug-loader
oneOf: [
// this applies to `<template lang="pug">` in Vue components
{
resourceQuery: /^\?vue/,
use: ['pug-plain-loader'] // PugPlugin.loader
},
// this applies to pug imports inside JavaScript
//{ issuer: /\.(js)$/, use: ['raw-loader', 'pug-plain-loader'] },
{
use: [PugPlugin.loader
/* "html-loader",
"pug-html-loader" */
]
}
],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: 'file-loader', // resolves import/require() on a file into a url and emits the file into the output directory
options: {
name: '[name].[ext]',
outputPath: 'images',
},
}
],
},
{
test: /\.(ttf|eot|woff|woff2|svg)$/i,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]', // fonts/
outputPath: 'fonts',
publicPath: "fonts",
},
},
}
]
},
plugins: [
// enable processing of Pug files defined in webpack entry
new PugPlugin({
js: { filename: 'scripts/[name].[contenthash:8].js', },
css: { filename: './styles/[name].[contenthash:8].css', },
}),
new VueLoaderPlugin(),
new MiniCssExtractPlugin({filename: './styles/[name].[contenthash:8].css'}),
new CopyPlugin({
patterns: [
{ from: `${__dirname}/images`, to: `${__dirname}/../client-dist/images` },
{ from: `${__dirname}/icons`, to: `${__dirname}/../client-dist/icons` },
{ from: `${__dirname}/fonts`, to: `${__dirname}/../client-dist/fonts` },
{ from: `${__dirname}/data`, to: `${__dirname}/../client-dist/data` },
],
}),
],
optimization: {
minimizer: [
// For webpack#5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
// `...`,
new CssMinimizerPlugin({
parallel: true,
}),
],
}
};
if (!devMode) {
config.plugins.push(
// new UglifyJSPlugin(),
/* new CopyWebpackPlugin([{ from: __dirname + '/src/public' }]) */
);
};
/* if (process.env.NODE_ENV === 'test') {
module.exports.externals = [require('webpack-node-externals')()]
module.exports.devtool = 'inline-cheap-module-source-map'
} */
module.exports = config;
There is a minimum of html/js/css for dist/production static files and the rest is compiles on server and fetched upon a request, for instance, if "about" page is requested of a page component is to be loaded, a server gets a .vue or pug/js/styl page or component, compiles it and fetches the static code to client.

Webpack chunks larger when building for production

When executing Webpack 4 for development and production mode the chunks for development are smaller than when built for production. I am currently using the following Webpack 4 configuration;
const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const DuplicatePackageCheckerPlugin = require('#cerner/duplicate-package-checker-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const bundleAnalyzerPlugin = new BundleAnalyzerPlugin();
/** ignore #anwb packages
* Keep warning for multiple react-is versions as warning
* * */
const duplicatePackageChecker = new DuplicatePackageCheckerPlugin({
verbose: true,
exclude(instance) {
// ignore #anwb packages
if (instance.name.includes('#anwb')) {
return true;
}
return false;
},
});
/** clean dist on build , webpack 5 supports clean property in output object * */
const cleanWebpackPlugin = new CleanWebpackPlugin();
module.exports = (env, argv) => {
const isDevelopment = argv.mode === 'development';
// No sourcemaps in production
// const devtool = isDevelopment ? { devtool: 'source-map' } : {};
const devtool = { devtool: 'source-map' };
// Separated output folders for OTA an P to separate artifacts in pipeline
const distFolder = isDevelopment ? 'distota' : 'dist';
console.log(`Webpack build for : ${isDevelopment ? 'development' : 'production'}`);
console.log(`Source maps included : ${Object.keys(devtool).length !== 0 ? 'yes' : 'no'}`);
console.log(`Build directory : ${distFolder}`);
return {
entry: {
index: path.resolve(__dirname, './src/index.tsx'),
},
/**
* Library target is set to umd so the anwb core js loading system can import it
*/
output: {
path: path.resolve(__dirname, `./${distFolder}`),
filename: '[name].js',
chunkFilename: '[name].js',
libraryTarget: 'umd',
publicPath: `/`,
},
resolve: {
/**
* Import files from the src or node_modules directory
*/
modules: ['src', 'node_modules'],
/**
* Load preact-compat when react is encountered
*/
alias: {
react: 'preact/compat',
'react-dom': 'preact/compat',
'#anwb/typography': path.resolve(__dirname, '.', 'node_modules', '#anwb/typography'),
},
extensions: ['.ts', '.tsx', '.js'],
},
bail: true,
/**
* Include source maps
*/
...devtool,
module: {
rules: [
/**
* The font is loaded using the fileloader and placed in a fonts folder
*/
{
test: /\.(eot|ttf|woff|woff2)$/,
loader: 'file-loader',
options: {
name: 'fonts/[name].[ext]',
},
},
/**
* The svg images are loaded and placed in the images directory
*/
{
test: /\.svg$/,
loader: 'file-loader',
options: {
name: 'images/[name][hash].[ext]',
},
},
/**
* All images bigger then 25000 bytes are placed in an images folder. Small images are included as inline base 64.
*/
{
test: /\.(png|jpg|gif)$/,
loader: 'url-loader',
options: {
limit: '25000',
name: 'images/[name][hash].[ext]',
},
},
/**
* All less files are converted down to css and are autoprefixed using the postcss module
*/
{
test: /\.(less|css)$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
{
loader: 'less-loader',
options: {
lessOptions: {
javascriptEnabled: true,
},
},
},
],
},
/**
* Js is transpiled using babel
*/
{
test: /\.(js|ts|tsx)$/,
exclude: ['/node_modules'],
include: [/src/, /node_modules\/#anwb/],
loader: 'babel-loader',
options: {
presets: [
[
'#babel/env',
{
modules: false,
targets: ['> 1% in NL', 'last 2 versions', 'last 5 iOS versions'],
// NewRelic uses Chrome 72 (2019). Therefore we need to Polyfill some features like Promise.allSettled.
// Story is made to remove it when NR is updated (MACS-13942)
useBuiltIns: 'usage',
corejs: { version: 3, proposals: true },
},
],
'#babel/react',
'#babel/flow',
],
plugins: [
['#babel/plugin-transform-react-jsx', { pragma: 'h' }],
'syntax-dynamic-import',
],
},
},
],
},
optimization: {
// splitChunks: {
// chunks: 'all',
// },
minimizer: [
new CssMinimizerPlugin({
test: /.css$/i,
minimizerOptions: {
preset: [
'default',
{
discardComments: { removeAll: true },
},
],
},
}),
new UglifyJsPlugin({
uglifyOptions: {
output: {
comments: false,
},
},
}),
],
},
plugins: [
bundleAnalyzerPlugin,
cleanWebpackPlugin,
/**
* The extract text plugin makes sure that all css is put into a single css file named after the application
*/
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[name].css',
}),
duplicatePackageChecker,
/**
* Dont use all moment locales
*/
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /nl/),
new webpack.DefinePlugin({
// "process.env": {
// NODE_ENV: simulateProduction ? JSON.stringify("production") : JSON.stringify("development")
// },
PRODUCTION: true,
}),
],
};
};
E.g. if the build is created for development the component has a stat size of 203KB
If the same build is run for production the same component has a stat size of 676KB
When the Webpack optimization is removed, this does not change. So i can rule this out.
Webpack is started using the two following package.json scripts;
"build": "webpack --config ./webpack.js --mode=production",
"build:ota": "webpack --config ./webpack.js --mode=development",
Any ideas how to optimize the chunks for production ?

Build failure while using Webpack4 in AngularJS1.5.11

I am working on an AngularJS Project to configure webpack for bundling purpose. I am using webpack4 for the same.
Below is the config file.
webpack.config.js:
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');// Require html-webpack-plugin plugin
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const ExtractNormalCSS = new ExtractTextPlugin("./src/main/frontend/sass/main.scss");
const extractCSS = new ExtractTextPlugin('/src/main/frontend/assets/icons/paas-icons/style.css');
module.exports = {
entry: [ "./src/main/frontend/app/app.js","./src/main/frontend/sass/main.scss"], // webpack entry point. Module to start building dependency graph
output: {
path: path.join(__dirname, '/distTemp/'), // Folder to store generated bundle
filename: '[name].bundle.js' // Name of generated bundle after build
//publicPath: '' // public URL of the output directory when referenced in a browser
},
resolve:{
modules: [
'node_modules',
'bower_components',
'src'
],
extensions:[".js"]
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
options: {
compact: false,
cacheDirectory: true,
presets: ['es2015', 'angular'],
},
},
{
test: /.(scss)$/,
loader: 'style-loader!css-loader!sass-loader'
},
{
test: /\.html$/,
loader: 'html-loader?name=views/[name].[ext]'
},
{
test: /\.(png|jpg)$/,
use: [
'url-loader?limit=8192'
]
},
]
},
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
compress: false,
ecma: 6,
mangle: false
},
sourceMap: true
})
],
splitChunks: {
cacheGroups: {
commons: {
test: /node_modules/,
name: 'vendor',
chunks: 'all'
}
}
}
},
plugins: [ // Array of plugins to apply to build chunk
new HtmlWebpackPlugin({
template: "./src/main/frontend/index.html",
inject: 'body'
}),
new ExtractTextPlugin('/distTemp/style/style.css'),
ExtractNormalCSS,
extractCSS
],
devServer: { // configuration for webpack-dev-server
contentBase: '.src/main/frontend/assets', //source of static assets
port: 7700, // port to run dev-server
}
};
Upon building, I am getting the error mentioned below.
ERROR in ./src/main/frontend/sass/main.scss (./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./src/main/frontend/sass/main.scss)
Module build failed (from ./node_modules/sass-loader/lib/loader.js):
var path = require("path");
^
Invalid CSS after "v": expected 1 selector or at-rule, was "var path = require("
in ###/node_modules/bourbon/index.js (line 1, column 1)
Error:
var path = require("path");
^
Invalid CSS after "v": expected 1 selector or at-rule, was "var path = require("
in ###/node_modules/bourbon/index.js (line 1, column 1)
at options.error (###/node_modules/node-sass/lib/index.js:291:26)
# ./src/main/frontend/sass/main.scss 2:14-134
# multi ./src/main/frontend/app/app.js ./src/main/frontend/sass/main.scss
I am using sass-loader and node-sass for the .scss files.
The main.scss file contains imports for the rest of the style files.
Could someone assist me in resolving this error please?

Webpack Hot Server Middleware not rendering with Webpack 4 and SSR

The 'serverRenderer is not a function' error pops us in development when adding webpack-hot-server-middleware. Below is my express.js and config/webpack.dev-ssr.js. Some issues on Github suggested webpack-hot-server-middleware loads before the compiler returns but I don't know how to verify that.
express.js:
import express from 'express';
import webpack from 'webpack';
import webpackHotServerMiddleware from 'webpack-hot-server-middleware';
import configDevClient from '../../config/webpack.dev-client'
import configDevSsr from '../../config/webpack.dev-ssr'
import configProdClient from '../../config/webpack.prod-client'
import configProdSsr from '../../config/webpack.prod-ssr'
const server = express()
const isDev = process.env.NODE_ENV !== 'production'
if (isDev) {
const compiler = webpack([configDevClient, configDevSsr])
const clientDevCompiler = compiler.compilers[0]
const ssrDevCompiler = compiler.compilers[1]
const webpackDevMiddleware = require('webpack-dev-middleware')(compiler, configDevClient.devServer)
const webpackHotMiddleware = require('webpack-hot-middleware')(clientDevCompiler, configDevClient.devServer)
server.use(webpackDevMiddleware)
server.use(webpackHotMiddleware)
// out of const compiler webpack-hot-server-middleware will take compiler with `name: 'server'`
server.use(webpackHotServerMiddleware(compiler))
} else {
webpack([configProdClient, configProdSsr]).run((err, stats) => {
// const staticMiddleware = express.static('dist')
// server.use(staticMiddleware)
const render = require('./render')
// const render = require('../../build/prod-ssr.bundle.js').default
const expressStaticGzip = require('express-static-gzip') // Heroku doesn't support gzip on Heroku server level
server.use(expressStaticGzip('dist', { enableBrotli: true }))
server.use(render())
})
}
const port = process.env.PORT || 8080
server.listen(port, () => console.log(`Server's running on http://localhost:${port}.`));
webpack.dev-ssr.js:
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const nodeExternals = require('webpack-node-externals');
const isProd = process.env.NODE_ENV === 'production';
module.exports = {
name: 'server', // preset name for webpack-hot-server-middleware
entry: {
server: './src/server/render'
},
resolve: {
extensions: ['.js'] // add extensions to entry files above
},
mode : 'production',
output : {
filename : 'dev-ssr.bundle.js',
path : path.resolve(__dirname, '../build'),
libraryTarget: 'commonjs2'
},
// for Node leave all required (with require()) modules as is don't put them to main.bundle.js like for browser
target: 'node',
/* Webpack allows to define externals - modules that should not be bundled.
When bundling with Webpack for the backend you usually don't want to bundle its node_modules dependencies.
This library creates an externals function that ignores node_modules when bundling in Webpack.
All Node modules will no longer be bundled but will be left as require('module'). */
externals: nodeExternals(),
/* optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
name: 'vendor',
chunks: 'initial',
minChunks: 2
}
}
}
}, */
devtool: 'source-map',
module : {
rules: [
{
test : /\.js$/,
use : [
{ loader: 'babel-loader' }
],
exclude: /node_modules/
},
{
test : /\.ts$/,
use : [
{ loader: 'awesome-typescript-loader' }
],
exclude: /node_modules/
},
{
test: /\.css$/,
use : [
{
loader: MiniCssExtractPlugin.loader
},
{
loader : 'css-loader',
options: {
sourceMap: true // won't work: no separate css file. Styles come from main.bundle.js
// minimize: true
}
}
]
},
{
test: /\.sass$/,
use : [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'sass-loader' }
]
},
{
test: /\.styl$/,
use : [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'postcss-loader' },
{ loader: 'stylus-loader' }
]
},
{
test: /\.less$/,
use : [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'less-loader' }
]
},
{
test: /\.html$/,
use : [
// job of two below modules are done by HtmlWebpackPlugin
/* {
loader: 'file-loader',
options: {
name: '[name].html' // output file name
}
},
{ // extract-loader puts the tested /\.html$/ file to a separate file not adds it to main.bundle.js
// extract loader parses the javascript back to an html file
loader: 'extract-loader'
}, */
// html-loader was left cause it exports tested html file as string to src/main.js
{
loader : 'html-loader', // exports tested html file to main.bundle.js as string and lints it
options: {
attrs: ['img:src'] // to add img:src to output file and require all images from its folder
}
// html template implicitly turns <img src='...' /> in .html page to <img src='require(src)' />
}
]
},
{
test: /\.pug$/,
use : [
{ loader: 'pug-loader' }
]
},
{
test: /\.hbs$/,
use : [
{
loader: 'handlebars-loader',
query : {
// hbs template implicitly turns <img src='...' /> in .hbs page to <img src='require(src)' />
inlineRequires: '/images/'
}
}
]
},
{
test: /\.(png|svg|gif|jpe?g)$/,
use : [
{
loader : 'file-loader',
options: {
name: '/images/[name].[hash:8].[ext]', // still emits not the file but its path
emitFile: false
}
}
]
},
{
test: /\.md$/,
use: [
/* { loader: 'html-loader' },
// markdown loader using 'marked' package. 'Marked' outputs HTML, it's best served with html-loader
{ loader: 'markdown-loader' } */
{ loader: 'markdown-with-front-matter-loader' }
]
}
]
},
plugins: [
new MiniCssExtractPlugin({ filename: '[name].[contenthash].css' }),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development')
}
})
]
};
The full repo is at https://github.com/ElAnonimo/webpack4
Missed the publicPath: '/' in the output section of '../../config/webpack.dev-client'.
Another possible reason and solution for this error is in the issue https://github.com/faceyspacey/react-universal-component/issues/148
Check this github issue
webpack explicit --mode may be affected your issue
https://github.com/webpack-contrib/webpack-hot-middleware/issues/255#issuecomment-375603384

Uncaught Syntax Error when running Vue.Js Unit Tests with Karma

I'm trying to get unit testing set up for my Vue JS project with Karma and Mocha (with vue-cli, I originally used Jest but I'm switching to Karma). I try to run my test with karma start; karma run and I keep getting:
09 03 2018 17:02:49.778:INFO [karma]: Karma v2.0.0 server started at http://0.0.0.0:9876/
09 03 2018 17:02:49.786:INFO [launcher]: Launching browser Chrome with unlimited concurrency
09 03 2018 17:02:49.797:INFO [launcher]: Starting browser Chrome
09 03 2018 17:02:54.410:INFO [Chrome 64.0.3282 (Windows 10.0.0)]: Connected on socket mvbOII8qli3NiwBMAAAA with id 62867001
Chrome 64.0.3282 (Windows 10.0.0) ERROR
{
"message": "Uncaught SyntaxError: Unexpected identifier\nat specs/PdfView.spec.js:3:8\n\nSyntaxError: Unexpected identifier",
"str": "Uncaught SyntaxError: Unexpected identifier\nat specs/PdfView.spec.js:3:8\n\nSyntaxError: Unexpected identifier"
}
The test runner starts, but I'm guessing some config issue is preventing the test from running properly. Also, it's not this just one component that will give me those errors.
My karma.conf.js file:
var webpackConfig = require('../../build/webpack.test.conf')
module.exports = function karmaConfig (config) {
config.set({
browsers: ['Chrome'],
frameworks: ['mocha'],
reporters: ['spec', 'coverage'],
files: ['specs/**/*.spec.js'],
preprocessors: {
'test/unit/spec/**/*.spec.js': [ 'webpack', 'sourcemap' ]
},
plugins: [
// Launchers
'karma-chrome-launcher',
// Test Libraries
'karma-mocha',
// 'karma-sinon-chai',
// Preprocessors
'karma-webpack',
'karma-sourcemap-loader',
// Reporters
'karma-spec-reporter',
'karma-coverage'
],
webpack: webpackConfig,
webpackMiddleware: {
noInfo: true
},
singleRun: true,
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' }
]
}
})
}
My .babelrc file:
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]
}
}
}
My webpack.test.conf.js:
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const webpackConfig = merge(baseWebpackConfig, {
// use inline sourcemap for karma-sourcemap-loader
module: {
rules: utils.styleLoaders(),
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
devtool: '#inline-source-map',
resolveLoader: {
alias: {
// necessary to to make lang="scss" work in test when using vue-loader's ?inject option
// see discussion at https://github.com/vuejs/vue-loader/issues/724
'scss-loader': 'sass-loader'
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/test.env')
})
]
})
delete webpackConfig.entry
module.exports = webpackConfig
PdfView.spec.js
import Vue from 'vue';
import Test from '#/components/Submission/PdfView';
describe('Test', () => {
it(`should render`, () => {
const Constructor = Vue.extend(Test);
const comp = new Constructor({}).$mount();
expect(comp.$el.textContent)
.to.equal('Test Text');
});
});
Webpack ^3.6.0,
Karma ^2.0.0,
Vue ^2.5.2
It looks to me like the # in import Test from '#/components/Submission/PdfView'; is not being resolved. Try adding this to your webpack.test.conf.js:
resolve: {
alias: {
'#': resolve('src')
}
}