Update:
I uploaded a sample project to github: https://github.com/guocheng/debug-webpack
In this sample project, I have two identical index.js file. One is under the project root, the other is under /src.
After npm install, run this command webpack-dev-server --config webpack.dev.config.js. You should see this error:
ERROR in ./index.js
Module parse failed: /Users/cheng/Dev/debug-webpack/index.js Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import React, { Component } from 'react';
|
| export default class App extends Component {
# multi main
But if you change Line #9 in the webpack.dev.config.js to ./src/index, the same command will work.
So the location of where I put index.js affects the output.
Any ideas of why this is happening?
Here is my .babelrc file:
{
"presets": ["es2015", "stage-0", "react"],
"plugins": ["transform-decorators-legacy", "transform-runtime"],
"ignore": ["node-modues/**/*.js"]
}
I do have babel-preset-2015, stage-0 and react installed.
I run the webpack-dev-server with this CLI command: node ./webpack/server.js
Here is server.js
const webpack = require('webpack'),
WebpackDevServer = require('webpack-dev-server'),
config = require('./dev.config')
new WebpackDevServer(webpack(config), {
contentBase: './build',
// webpack-dev-server options
hot: true,
historyApiFallback: true,
inline: true,
// webpack-dev-middleware options
noInfo: false,
quiet: false,
lazy: false,
publicPath: config.output.publicPath,
headers: {'Access-Control-Allow-Origin': '*'},
stats: { colors: true }
}).listen(port, ip, function(err, result) {
if (err) {
console.log(err)
}
})
Here is the webpack config file I used:
const webpack = require('webpack'),
path = require('path'),
ExtractTextPlugin = require('extract-text-webpack-plugin')
const PATHS = {
app: path.join(__dirname, 'app'),
build: path.join(__dirname, 'build'),
dist: path.join(__dirname, 'dist')
}
module.exports = {
devtool: 'inline-source-map',
entry: {
javascript: [
'webpack-dev-server/client?http://127.0.0.1:5555',
'webpack/hot/only-dev-server',
'./app/index.js'
]
},
output: {
path: PATHS.dist,
filename: 'bundle.js',
publicPath: '/static/'
},
module: {
loaders: [{
test: /\.jsx?$/,
loaders: ['react-hot', 'babel?cacheDirectory'],
exclude: /(node_modules|bower_components)/,
include: path.join(__dirname, 'app'),
},{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!cssnext-loader')
},{
test: /\.(woff|woff2|eot|ttf)$/,
loader: 'url-loader?limit=8192&name=fonts/[name].[ext]'
},{
test: /\.(png|jpg|svg)$/,
loader: 'url-loader?limit=8192&name=img/[name].[ext]'
}]
},
cssnext: {
browsers: 'last 2 versions'
},
resolve: {
extensions: ['', '.js', '.jsx']
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new ExtractTextPlugin(
'bundle.css',
{allChunks: true}),
new webpack.DefinePlugin({
'__DEVELOPMENT__': true,
'__DEVTOOLS__': true
})
]
}
When I run the dev server, here is the error message:
ERROR in ./app/index.js
Module parse failed: /Users/cheng/Dev/note/note-client/app/index.js Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import React from 'react'
| import ReactDOM from 'react-dom'
| import { Provider } from 'react-redux'
# multi javascript
For some reason, the presets didn't kick in. I tried to use babel CLI to test the file manually:
babel index.js // note: .babelrc is used for configuring the presets
I can actually see the correct output. Any suggestions on what might be causing the issues?
Package versions I have installed:
├── babel-core#6.7.2
├── babel-eslint#5.0.0
├── babel-loader#6.2.3
├── babel-plugin-transform-decorators-legacy#1.3.4
├── babel-plugin-transform-runtime#6.6.0
├── babel-preset-es2015#6.6.0
├── babel-preset-react#6.5.0
├── babel-preset-stage-0#6.5.0
├── webpack-dev-server#1.14.1
Here is my project fold's structure:
project_name
|── app
|── index.js
|── dist
|── build
|── webpack
|── dev.config.js
|── server.js
|── .babelrc
I tried to run the following command at project root, and it gives me the same error:
webpack-dev-server --config ./webpack/dev.config.js
but babel ./app/index.js works.
You have invalid include path in js loader since your config is located in webpack directory:
{
test: /\.jsx?$/,
loaders: ['react-hot', 'babel?cacheDirectory'],
exclude: /(node_modules|bower_components)/,
include: path.join(__dirname, 'app'),
}
Include path in your case is root/webpack/app and must be root/webpack/../app:
path.join(__dirname, '..', 'app')
Related
I have the following structure:
└── src
├── tsconfig.json
├── core
│ ├── [...].ts
└── ui
├── [...].tsx
└── tsconfig.json
In the frontend I import a small number of modules from the core. These modules, and any dependent modules, are compliant with both tsconfig files.
tsc and eslint pass with no errors and webpack builds the desired output file. So far so good.
However when webpack builds it throws loads of type errors for other backend modules.
How do I suppress these errors? I tried excluding src/core from babel-loader and including the required modules but I was still getting the same errors.
/// webpack.config.js
/* eslint-disable #typescript-eslint/no-var-requires */
const path = require('path');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/ui',
output: {
path: path.resolve(__dirname, './ui-dist'),
},
// Enable sourcemaps for debugging webpack's output.
devtool: 'source-map',
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: ['.ts', '.tsx', '.js', '.jsx'],
},
module: {
rules: [
{
test: /\.(j|t)sx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
babelrc: false,
presets: [
[
'#babel/preset-env',
{ targets: { browsers: 'last 2 versions' } }, // or whatever your project requires
],
'#babel/preset-typescript',
'#babel/preset-react',
],
plugins: [
// plugin-proposal-decorators is only needed if you're using experimental decorators
// in TypeScript
['#babel/plugin-proposal-decorators', { legacy: true }],
['#babel/plugin-transform-runtime', { legacy: true }],
['#babel/plugin-proposal-class-properties', { loose: true }],
'react-hot-loader/babel',
],
},
},
},
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader',
},
],
},
plugins: [
new ForkTsCheckerWebpackPlugin({
tsconfig: path.resolve(__dirname, './src/ui/tsconfig.json'),
eslint: true,
/** Options to supply to eslint https://eslint.org/docs/developer-guide/nodejs-api#cliengine */
// eslintOptions: EslintOptions;
}),
new HtmlWebpackPlugin({
title: 'development',
template: './src/ui/template.html',
}),
],
// When importing a module whose path matches one of the following, just
// assume a corresponding global variable exists and use that instead.
// This is important because it allows us to avoid bundling all of our
// dependencies, which allows browsers to cache those libraries between builds.
// externals: {
// react: 'React',
// 'react-dom': 'ReactDOM',
// },
devServer: {
contentBase: path.resolve(__dirname, './ui-dist'),
},
};
EDIT: I suppose I am referencing these modules throwing an error by using import type { x } from '../core/index.ts'. Perhaps I need to find a way for babel-loader to skip scanning type imports.
removing ForkTsCheckerWebpackPlugin did the trick. Type checking is done when calling tsc in any case.
I have a Node Js server that I bundled with webpack with the following config:
module.exports = {
entry: './build/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
devtoolModuleFilenameTemplate: '../[resource-path]',
},
target: 'node',
node: {
__dirname: true,
},
externals: {
kcors: 'kcors',
'koa-bodyparser': 'koa-bodyparser'
},
module: {
rules: [
{
test: /\.js$/,
use: ["source-map-loader"],
enforce: "pre"
},
],
},
resolve: {
extensions: ['.js'],
},
// plugins: [
// new webpack.DefinePlugin({
// "process.env": JSON.stringify(dotenv.parsed)
// }),
// ],
devtool: 'eval-source-map'
};
This created a single file main.js inside dist
Everything looks good so far. I manually tested the server and it works.
Now, before I used webpack, I have a set of unit tests that I named with the .spec.js suffix inside my entry folder (the build/ folder) and each .js file has each own .spec file sibling located in the same directory of the .js.
To run theses unit test, I used mocha with the command: mocha build/**/*.spec.js --recursive --timeout 20000
Since I am new to webpack and the concept of bundling, how do I run the same tests from the main.js file ? I want to make sure that all tests are still passing in the bundled file
use
npm install mocha mocha-loader
config your webpack.config.js file like:
module.exports = {
entry: './entry.js',
output: {
path: __dirname,
filename: 'bundle.js',
},
module: {
rules: [
{
test: /test\.js$/,
use: 'mocha-loader',
exclude: /node_modules/,
},
],
},
};
then, call your test file from your main file like:
(into app.js)
import test from 'allMyTests';
So I'm trying to learn Vue.js + webpack and initated a project by following these steps:
f:www\> npm install -g vue-cli
f:www\> vue init webpack-simple my-project
f:www\> cd my-project
f:www\> npm install
f:www\> npm run dev
The default page runs on http://localhost:8080/.
Now, in webpack.config.jsfile I have the following lines:
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'main.js'
},
and in the index.html we find the following line <script src="/dist/main.js"></script>
At this point I thought Webpack was a bit like Gulp in that it compiles src files and puts them in the /dist/ folder.
But Webpack never creates the /dist/ folder.
How can the Vue logo be loaded from <img src="/dist/logo.png?82b9c7a5a3f405032b1db71a25f67021"> when /dist/ folder does not exist?
Why is main.js not created?
webpack.config.js (short version)
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'main.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
],
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['*', '.js', '.vue', '.json']
},
devServer: {
historyApiFallback: true,
noInfo: true,
overlay: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
};
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map';
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
So after some more googling, I found this turorial that explains the entire webpack-simple setup.
Here is the section regarding the /dist/ folder:
npm run build
Right now we are simply using npm run dev to work with and test out an
installation of the Vue Cli tool. This is great
for testing in the local environment, but what about if you actually
want to publish your application to the web? In this case you will
instead run npm run build. This will build your application for
production and you’ll see a new /dist/ folder which contains the
finished bundle.
So during development, the files are placed in a chached / temp location (not sure where)
I am using webpack for the first time and want to use some css with my react/redux application. I followed a guide, but still seem to be having problems. I am getting the above error as you can see.
folder structure looks like this:
.git
-node_modules
-public
-bundle.js
-index.html
-src
-actions
-components
-reducers
app.js
-style
-style.css
.babelrc
.gitingore
package-lock.json
package.json
README.md
server.js
webpack.config.js
This is the exact error:
Uncaught Error: Module parse failed: C:\Users\Amazo\projects\reduxApp\style\style.css Unexpected character '#' (1:0)
You may need an appropriate loader to handle this file type.
| #row1 {
| margin-top: 15px;
| }
I will post my webpack config file below:
var path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
var HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/app.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'public')
},
watch: true,
module: {
rules: [
{
test: /\.js$/,
exclude:/node_modules/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-1']
}
},
{
use: ['style-loader', 'css-loader'],
test: /\.css$/
}
]
},
resolve: {
extensions: ['.js','.jsx']
},
plugins: [
new HTMLWebpackPlugin({
template: 'public/index.html';
}),
new ExtractTextPlugin('style.css')
]
};
Add .css to your resolve
resolve: {
extensions: ['.js','.jsx', '.css']
},
Otherwise, webpack won't be able to process it correctly
I am trying to set up webpack hot reloading with react-hot-loader. It mostly seems to be working. I am using webpack in an existing rails app.
But it isn't hot-reloading. It is simply triggering a reload every time my react code is changed. The error messages I get are:
[HMR] Cannot apply update. Need to do a full reload! - dev-server.js:18
[HMR] Error: Aborted because 0 is not accepted - dev-server.js:19
at hotApply (http://localhost:8080/assets/webpack/bundle.js?body=1:380:31)
at hotUpdateDownloaded (http://localhost:8080/assets/webpack/bundle.js?body=1:293:13)
at hotAddUpdateChunk (http://localhost:8080/assets/webpack/bundle.js?body=1:273:13)
at webpackHotUpdateCallback (http://localhost:8080/assets/webpack/bundle.js?body=1:5:12)
at http://localhost:8080/assets/webpack0.bd89931b2fa8e2901794.hot-update.js:1:1
Navigated to http://lvh.me:3000/react_page
Here is my webpack.hot.config.js settings:
var path = require('path');
var webpack = require('webpack');
var config = module.exports = {
// Set 'context' for Rails Asset Pipeline
context: __dirname,
entry: {
App: [
'webpack-dev-server/client?http://localhost:8080/', // WebpackDevServer host and port
'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
'./app/frontend/javascripts/app.js' // Your appʼs entry point
],
vendor: ['jquery', 'react', 'react-dom', 'react-redux', 'redux','redux-thunk']
},
devtool: 'inline-source-map',
// Require the webpack and react-hot-loader plugins
plugins: [
//new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.CommonsChunkPlugin(
{
name: 'vendor',
chunks: [''],
filename: 'vendor.js',
minChunks: Infinity
}),
new webpack.NoErrorsPlugin(),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jquery': 'jquery'
})
],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: [
'react-hot',
'babel?presets[]=es2015&presets[]=react'
],
cacheDirectory: true
}
]
},
output: {
path: path.join(__dirname, 'app', 'assets', 'javascripts', 'webpack'), // Save to Rails Asset Pipeline
filename: 'bundle.js', // Will output App_wp_bundle.js
publicPath: 'http://localhost:8080/assets/webpack',
//publicPath: 'http://localhost:8080/assets/webpack' // Required for webpack-dev-server
},
resolve: {
extensions: ['', '.js', '.jsx'],
modulesDirectories: ['node_modules'],
},
};
And I run the code with
webpack-dev-server -d --config webpack.hot.config.js --hot --inline
The rails development environment serves the webpack files outside the application asset pipeline via the webpack-dev-server because of the following setting in my development.rb file.
config.action_controller.asset_host = Proc.new { |source|
if source =~ /webpack\/bundle\.js$/i
"http://localhost:8080"
end
}
I have been trying to get this working for hours. Any help would be appreciated.
Thanks guys!
Ok i was getting the same error, but after trying some things out i figured this out: My root component was a stateless functional component (pure function). I refactored it to a class component and BAM! the hot reloading is working again.
Before:
const App = (props) => (
<div>
<Header links={headerLinks} logoSrc={logoSrc} />
{props.children}
</div>
);
After:
class App extends React.Component {
render() {
return (
<div>
<Header links={headerLinks} logoSrc={logoSrc} />
{this.props.children}
</div>
);
}
}
As the answers provided above are still not working on my side with webpack 5,
Here is the working config from webpack
In webpack.config.js
devServer: {
.
.
.
hot: true,
}
In the webpack entrypoint index.js add
if (module.hot) {
module.hot.accept();
}
In package.json start script
"scripts": {
.
.
"start": "webpack serve --config /webpack.config.js"
},
I recently ran into this exact issue, the fix for me was removing this from the entries array: 'webpack-dev-server/client?http://localhost:9000/',.
As I was also running --hot as a command line argument, there were two instances of webpack-dev-server getting into a bad state.
I don't know if this will specifically help your issue, but I encountered this error recently as well - i fixed it by adding a .js extension to the module I was trying to set up with hmr - here was my code
if (module.hot) {
module.hot.accept('app/Routes', () => (
getRoutes = require('app/Routes')
))
}
I updated it to getRoutes = require('app/Routes.js') and the error disappeared, using webpack ^2.0.0-beta.
it also works if i add the JS extension as the first argument of hot accept like so:
if (module.hot) {
module.hot.accept('app/Routes.js', () => (
getRoutes = require('app/Routes')
))
}
so now it matches whats on the webpack HMR page
I ran into a similar problem.
After 2 days of research and trying different things, I found out the simplest cause to my problem ever:
in webpack.config.js, I had a HRM dev server enabled. And I also had a HMR server run from command line. Thanks to hint from Tyler Kelley (see above), just by removing --hot from command line, it works OK now.
current webpack.config.js
devtool: "inline-source-map",
devServer: {
publicPath: '/dist/',
contentBase: path.join(__dirname, 'public'),
port: 9000,
hot: true
},
With this configuration, don't do this:
npx webpack-dev-server --hot --inline
Do this:
npx webpack-dev-server
For "webpack": "^5.74.0" and "webpack-dev-server": "^4.11.1".
I set devServer.static = ['./webpack-dev-server', './dist'], in webpack.config.js.
There is my config:
module.exports = {
devtool: 'inline-source-map',
devServer: {
open: true,
static: ['./webpack-dev-server', './dist']
},
entry: path.join(__dirname, 'src', 'index.ts'),
module: {
rules: [
{
test: /\.(ttf|png|svg|jpg|jpeg)$/i,
type: 'asset/resource',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.ts$/,
loader: 'ts-loader',
options: {
configFile: path.join(__dirname, 'tsconfig.json')
}
}
]
},
mode: 'development',
output: {
filename: '[name][contenthash].js',
path: path.join(__dirname, 'dist'),
clean: true,
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'index.html'),
inject: 'body'
})
],
resolve: {
extensions: ['.js', '.ts']
}
}