Jest webpack 4 babel 7 syntaxError 'import' inside .test.js files - reactjs

Setup
react 16.4.2 (not cra, homebrewed)
babel v7
jest v24
webpack v4.17
PROBLEM
getting error below when I use 'import' syntax inside my test files (i.e. inside component.test.js).
How can I tell Jest to parse the test files using es6?
Have done a lot of googling but no joy
C:\repos\sandbox\my_react_starter\src\temp.test.js:2
import React from 'react';
^^^^^^
SyntaxError: Unexpected token import
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:471:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:513:25)
jest config:
"jest": {
"rootDir": ".",
"verbose": true,
"transform": {
"^.+\\.jsx?$": "babel-jest",
".+\\.(css|styl|less|sass|scss)$": "<rootDir>/node_modules/jest-css-modules-transform"
}
},
.babelrc
{
"presets": [
"#babel/preset-env",
"#babel/react"
],
"env": {
"test": {
"plugins": [
"transform-es2015-modules-commonjs"
]
}
}
}
webpack:
module.exports = {
entry: './src/index.js',
output: { path: __dirname + '/dist', publicPath: '/', filename: 'bundle.js' },
devServer: { contentBase: './dist' },
module:
{
rules:
[
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: { presets: ['es2015'] }
}
}
]
}
};

Related

Webpack devServer updates everything except the webpage

I'm creating a pretty basic app and using webpack with hot reloader. Everything worked fine until I noticed the hotreload stopped working. I can't figure out why.
This is my package.json:
"start": "webpack serve --config ./webpack.config.js --mode development",
This is my webpack.config.js:
const config = {
entry: {
app: path.resolve(__dirname, './src/index.jsx')
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, '../dist'),
publicPath: '/',
chunkFilename: '[name].bundle.js',
},
resolve: {
extensions: ['*', '.js', '.jsx'],
},
devServer: {
hot: true,
devMiddleware: {
writeToDisk: (filePath) => {
return !(/hot-update\.(js|json)$/.test(filePath));
},
},
static: {
directory: path.join(__dirname, '/public'),
},
},
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.(js|jsx)$/,
loader: 'babel-loader',
exclude: /node_modules/,
options:{
presets: ['#babel/react', '#babel/preset-env']
}
},
{
test: /\.tsx?$/,
loader: "ts-loader"
}
]
}
};
Here is the screenshot from my browser:
The bundle js file itself is updated.
But the browser remains unchanged.

Webpack watch compiles my scss sass but not webpack-dev-server

I am able to compile my sass successfully with webpack using the webpack --watch command, but it does not perform hot module replacement.
I am able to do HMR successfully with the webpack-dev-server --hot --progress --colors --inline command, and it reloads with my .js changes, but not my .scss/.css ones.
I've noticed that when I change a sass file the server refreshes, but the styles aren't updated. I want to make sure I'm doing it with just one command.
Here's the scripts from my package.json
"scripts": {
"build": "webpack -p",
"watch": "webpack --watch",
"start": "webpack-dev-server --hot --progress --colors --inline"
},
and here's my entire webpack config:
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const webpack = require('webpack');
const path = require("path");
module.exports = {
entry: {
master: "./src/index.jsx"
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js"
},
module: {
rules: [
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader", "sass-loader"],
publicPath: "dist"
})
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: "babel-loader"
},
]
},
resolve: {
extensions: [".js", ".jsx"]
},
plugins: [
new ExtractTextPlugin({
filename: "master.css",
allChunks: true
}),
new webpack.HotModuleReplacementPlugin()
],
devServer: {
contentBase: './dist',
hot: true,
port: 3000,
host: '0.0.0.0',
inline: true,
disableHostCheck: true,
}
};
and, in case it's necessary, here's my .babelrc (I'm using React):
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-transform-runtime",
"react-hot-loader/babel"
]
}
How do I get my webpack dev server to reload with my compiled sass changes as I change them?
I eventually figured this out with the following setup. I think the issue was related to the fact that both watch and webpack dev server were in the webpack config - and I realized that watch mode is not needed in my setup if I'm running webpack dev server:
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const webpack = require('webpack');
const path = require("path");
module.exports = {
entry: {
master: "./src/index.jsx"
},
watch: true,
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js"
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: ["babel-loader"]
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader", "sass-loader"],
publicPath: "dist"
})
},
]
},
resolve: {
extensions: [".js", ".jsx"]
},
plugins: [
new ExtractTextPlugin({
filename: "master.css",
allChunks: true
}),
new webpack.HotModuleReplacementPlugin()
],
devServer: {
contentBase: './dist',
hot: true,
port: 3000,
host: '0.0.0.0',
inline: true,
disableHostCheck: true,
watchOptions: {
ignored: [
path.resolve(__dirname, 'node_modules')
]
}
}
};
and package.json:
"scripts": {
"start": "webpack-dev-server",
"dist": ""
},
You can view my full config here
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
],
module: {
rules: [{
test: /\.scss$/,
use: [
'style-loader',
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
minimize: true,
sourceMap: true
}
},
{
loader: "sass-loader"
}
]
}
]
}

webpack bundle file is not being generated with no errors

I am new to react, trying to learn webpack configuration. I am using webpack4 for my project, however, after setting up webpack, the bundle files are not generated, neither the js file nor the html file and there is no error.
The output on the console says "compiled successfully". How do i fix this. I have been struggling for about a week and no online resource seems to give me what i want.
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const port = process.env.PORT || 3000;
const paths = {
DIST: path.resolve(__dirname, 'dist'),
SRC: path.resolve(__dirname, 'src'),
JS: path.resolve(__dirname, 'src/js')
}
const htmlPlugin = new HtmlWebpackPlugin({
template: "./src/index.html",
filename: "./index.html"
});
module.exports = {
mode: 'development',
entry: path.join(paths.JS, 'index.js'),
output: {
path: paths.DIST,
filename: 'app.bundle.js'
},
module:{
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options:{
modules: true,
importLoaders: 1,
localIndentName: "[name]_[local]_[hash:base64]",
sourceMap: true,
minimize: true,
camelCase:true
}
}
]
}
]
},
plugins: [htmlPlugin],
devServer: {
publicPath: paths.DIST,
host: 'localhost',
port: port,
historyApiFallback: true,
open:true,
hot: true
}
};
Make sure all path correctly, not have missing file.
src/js/index.js
src/index.html
make sure run webpack correctly to show log like:
package.json
"scripts": {
"start": "webpack --config webpack.config.js --bail --progress --profile"
},
and run by npm start, then will show the log.
if you want, you can use new babel version. change your bable with this:
"dependencies": {
"#babel/core": "^7.0.0-beta.42",
"#babel/preset-env": "^7.0.0-beta.42",
"babel-eslint": "^8.0.3",
"babel-loader": "^8.0.0-beta.0",
"css-loader": "^0.28.11",
"html-webpack-plugin": "^3.1.0",
...
"style-loader": "^0.20.3",
"webpack": "^4.4.1",
"webpack-cli": "^2.0.13"
},
.babelrc
{
"presets": ["#babel/preset-env"],
"plugins": ["#babel/plugin-proposal-object-rest-spread"]
}
then update your webpack rule:
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env'],
plugins: [require('#babel/plugin-proposal-object-rest-spread')]
}
},
exclude: /node_modules/
},

React Not Attaching DOM to the HTML

I am having some problem in my ReactJs code. Everything is compiling without any error using webpack. But after webpack dev server started and when I am browsing to localhost:9000 nothing is inserted into the DOM from ReactJs.
I am running npm start on terminal.
Here is all the code that i have written -
.babelrc
{
"presets": ["es2015", "react", "stage-0"]
}
.eslintrc
{
"ecmaFeatures": {
"jsx": true,
"modules": true
},
"env": {
"browser": true,
"node": true
},
"parser": "babel-eslint",
"rules": {
"quotes": [2, "single"],
"strict": [2, "never"],
"react/jsx-uses-react": 2,
"react/jsx-uses-vars": 2,
"react/react-in-jsx-scope": 2
},
"plugins": [
"react"
]
}
.jslintrc
{
"node": true,
"browser": true,
"esnext": true,
"newcap": false
}
index.html
<html>
<head>
<title>Forms in React Test</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
</head>
<body>
<div id='root' class="container">
</div>
</body>
<script src="/static/bundle.js" type="text/javascript"></script>
</html>
index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class IndexComponent extends React.Component{
render() {
return (
<div>
<input type="text" value="Shawn" />
</div>
);
}
}
ReactDOM.render(<IndexComponent />, document.getElementById('root'));
**package.json**
{
"name": "chapter4",
"version": "0.0.1",
"description": "ReactJS forms example",
"scripts": {
"start": "node server.js",
"lint": "eslint src"
},
"author": "",
"license": "MIT",
"homepage": "",
"devDependencies": {
"babel": "^6.23.0",
"babel-cli": "^6.24.1",
"babel-core": "^6.24.1",
"babel-eslint": "^7.2.2",
"babel-loader": "^6.4.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"eslint": "^3.19.0",
"eslint-plugin-react": "^6.10.3",
"react-hot-loader": "^1.3.1",
"webpack": "^2.4.1",
"webpack-dev-server": "^2.4.2"
},
"dependencies": {
"react": "^15.5.4",
"react-dom": "^15.5.4"
}
}
webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:9000',
'webpack/hot/only-dev-server',
'./src/index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
// new webpack.NoEmitOnErrorsPlugin()
],
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.jsx?$/,
include: [path.join(__dirname, 'src')],
},
{
use: [
{
loader: 'react-hot-loader'
},
{
loader: 'babel-loader',
options: {
// cacheDirectory: 'babel_cache',
presets: ['react', 'es2015']
}
}
]
}
]
}
};
Thank you all in advance.
In your webpack.confg.js you have the following:
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:9000',
'webpack/hot/only-dev-server',
'./src/index' // <-- no src dir in project
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
// new webpack.NoEmitOnErrorsPlugin()
],
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.jsx?$/,
include: [path.join(__dirname, 'src')], // <-- no src dir in project
},
{
use: [
{
loader: 'react-hot-loader'
},
{
loader: 'babel-loader',
options: {
// cacheDirectory: 'babel_cache',
presets: ['react', 'es2015']
}
}
]
}
]
}
};
You don't have a src directory in this project.
Fix: Make a src directory and move your index.js file in it. You also have a problem with the way you're trying to bring in react-hot-loader and not excluding node_modules. Try this for your module section:
module: {
loaders: [
{
test: /\.jsx?$/,
loaders: ['react-hot-loader', 'babel-loader?presets[]=es2015&presets[]=react&presets[]=stage-2&presets[]=stage-0'],
include: [path.join(__dirname, 'src')],
exclude: '/node_modules/'
}
]
}
Tested and it works on my local.
Got the solution.
In the rules part I am doing some mistake. Following will be the correct rules.
rules: [{
test: /\.jsx?$/,
include: [path.join(__dirname, 'src/')],
use: [
{
loader: 'react-hot-loader'
},
{
loader: 'babel-loader',
}
]
}]
This will be the correct webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:9000',
'webpack/hot/only-dev-server',
path.resolve(__dirname, 'src/')
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
],
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [{
test: /\.jsx?$/,
include: [path.join(__dirname, 'src/')],
use: [
{
loader: 'react-hot-loader'
},
{
loader: 'babel-loader',
}
]
}]
}
};
Thanks to all for the help.

Webpack output not in desired directories

Very simple app here. Started with the demo found here, and modified it to use Babel 6. The problem I have is that the output of webpack puts my HTML files in a subdirectory of the output Dist directory.
Starting with this file structure:
Test|
|package.json
|webpack.config.js
|app|
|index.html
|js|
|app.js
|greeting.js
What I end up with after running webpack is this in my dist directory:
dist|
|app.js
|app|
|index.html
Seems odd to me. What I want is this:
dist|
|index.html
|app|
|app.js
Here's the webpack.config.js file:
module.exports = {
context: __dirname + "/app",
entry: {
javascript: "./js/app.js",
html: "./index.html",
},
output: {
filename: "app.js",
path: __dirname + "/dist",
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query:
{
cacheDirectory: true,
presets: [ 'react', 'es2015' ]
}
},
{
test: /\.html$/,
loader: "file?name=[name].[ext]",
}
],
}
}
package.json:
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.html",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.7.4",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"file-loader": "^0.8.5",
"react-dom": "^0.14.8",
"webpack": "^1.12.14"
},
"dependencies": {
"react": "^0.14.8"
}
}
I'm close to getting this where I can get to the next step. How do I get webpack to pack the output like I want?
I'm new to webpack, so I don't know if this is the best solution, but this should work (output.path and file loader have been modified) :
module.exports = {
context: __dirname + "/app",
entry: {
javascript: "./js/app.js",
html: "./index.html",
},
output: {
filename: "app.js",
path: __dirname + "/dist/app",
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query:
{
cacheDirectory: true,
presets: [ 'react', 'es2015' ]
}
},
{
test: /\.html$/,
loader: "file?name=../[name].[ext]",
}
],
}
};
According to the documentation, the context option is only used to resolve the entry point.
One way to do it, is get the htmlwepackplugin, and adjust your config as below. this would also inject the script build, so you dont have to have it on your index.html ;)
module.exports = {
context: __dirname + "/app",
entry: {
javascript: "./js/app.js",
html: "./index.html",
},
output: {
filename: "app.js",
path: __dirname + "/dist/app",
},
module: {
plugins: [
new HtmlWebpackPlugin({filename: '../index.html', template: './test/app/index.html', chunksSortMode: 'none'}),
],
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query:
{
cacheDirectory: true,
presets: [ 'react', 'es2015' ]
}
},
{
test: /\.html$/,
loader: "file?name=[name].[ext]",
}
],
}
}

Resources