I use webpack and react in this project, and I want to import react-paginator in my project, but I get an error when I bundle front-end code.
I guess webpack did not parse the jsx code under node_modules folder, but I have no ideas how to solve......
error:
ERROR in ./~/react-paginator/index.js
Module parse failed: /home/kang/Desktop/doing/match-platform/node_modules/react-paginator/index.js Line 109: Unexpected token <
You may need an appropriate loader to handle this file type.
webpack config:
var webpack = require('webpack');
module.exports = {
entry: {
root: './src/front_end/scripts/root_container.js',
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets:['es2015', 'react']
}
}, {
test: /\.json$/,
loader: 'json'
}]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
output: {
path: './src/front_end/dist',
publicPath: '/',
filename: 'bundle.js'
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'root.jQuery': 'jquery',
'Promise': 'exports?global.Promise!es6-promise',
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch',
}),
new webpack.DefinePlugin({
"require.specified": "require.resolve"
}),
]
};
The problem is that react-paginator's source hasn't been precompiled to a format that would work out of box. It still contains JSX. That's why the code fails for you.
To solve this you will have to compile the code yourself. You could try to add an include like this to your jsx loader definition:
include: path.join(__dirname, 'node_modules/react-paginator')
This should help webpack to compile the file for you.
On a related note I've developed an alternative component you could look into. See react-pagify. It should work without any fiddling on your part. It's more complicated to use by design, though.
Related
I am getting started to migrate my angular app to webpack. I have a file structure as belows:
- app/
------ app.js
------ index.html
- lib/
----- angular.js
----- jquery.js
----- ...
- webpack.config.js
Due to restrictions, I cannot use npm to install libraries. All my library files are located in lib and other folders. My webpack config looks like below:
var webpack = require('webpack'),
path = require('path');
module.exports = {
context: __dirname,
entry: {
app: [ './app/app.js'],
vendors: ['angular']
},
output: {
path: __dirname + '/build',
filename: 'bundle.js'
},
resolve: {
alias: {
angular: __dirname + "/lib/angular"
}
},
debug: false,
devtool: 'source-map',
module: {
loaders: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
},
{
test: /\.css$/,
loader: "style-loader!css-loader"},
{
test: /\.png$/,
loader: "url-loader?limit=100000"},
{
test: /\.jpg$/,
loader: "file-loader"
},
{
test: /\.json/,
loader: 'json'
}
]
},
plugins: [
new webpack.ProvidePlugin({
angular: "angular"
}),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js', Infinity)
]
}
I get the error
angular.js?848f:80Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:nomod] Module 'myApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
app.js looks like below
angular.module("myApp", [])
.controller("myCtrl", function(){ ... });
Thanks for the help!
First, fix typo vendor instead of vendors in your entries. It should match name in CommonsChunkPlugin
entry: {
app: [ './app/app.js'],
vendor: ['angular']
},
Second, remove ProvidePlugin
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js', Infinity)
]
Now it should works.
But i don't know if it's correct way to load external libs with webpack, actually. (Webpack is super black box for me, gulp is much more predictable). So now it works, but without proper DI.
I am using webpack with babel-loader to transform .jsx react files.
However, adding a file-loader or style- and css-loader does not correctly process the images required() in the react components or style sheets.
They get recognized by webpack and copied to the dist folder. The path to the image file is correct, I've verified this in the css and js output.
The server is also able to display the files, I've checked with some manually copied ones.
What is happening is that the images themselves get corrupted. No image viewer nor the browser can display the image which results in an invisible image in the browser.
What I've tried so far:
using only babel-loader as suggested in: https://github.com/webpack/file-loader/issues/35, results in Error: No handler for file type.
using file-loader directly
using image-webpack-loader (which seems to be using file-loader under the hood)
using IsomorphicLoaderPlugin (https://github.com/jchip/isomorphic-loader) which seems to be a simpler alternative to webpack-isomorphic-tools
using css background-images with url() and ExtractTextPlugin('style-loader", 'css-loader')
All of the above steps resulted in either errors with webpack not finding an appropriate handler or corrupted image files.
Here is my current webpack config for reference (I've included all of it in case there are any problems/conflicts I am overlooking):
var ExtractTextPlugin = require('extract-text-webpack-plugin'),
webpack = require('webpack');
IsomorphicLoaderPlugin = require("isomorphic-loader/lib/webpack-plugin");
module.exports = {
context: __dirname + '/client',
entry: ['babel-polyfill', './index.jsx'],
output: {
filename: 'app.js',
path: __dirname + '/dist',
publicPath: '/'
},
resolve: {
ignore: /node_modules/,
extensions: ['', '.js', '.jsx']
},
devtool: 'source-map',
plugins: [
new ExtractTextPlugin('styles.css'),
new IsomorphicLoaderPlugin({ keepExistingConfig: false }),
new webpack.DefinePlugin({
"process.env": {
BROWSER: JSON.stringify(true)
}
})
],
module: {
preLoaders: [
{
loaders: ['isomorphine']
}
],
loaders: [
{
test: /\.jsx?$/,
loader: 'babel',
exclude: /node_modules/,
query: {
cacheDirectory: true,
plugins: ['transform-runtime', 'transform-decorators-legacy', 'transform-class-properties', 'transform-object-rest-spread'],
presets: ['react', 'es2015', 'stage-0']
}
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: "file!isomorphic"
}
]
}
};
Does anyone see what I'm doing wrong here in my webpack.config.js file? The browser gives me an error saying "unexpected token 'import' " which means it is not recognizing ES6 syntax. Am I doing something wrong with the loaders? I've installed and reinstalled dependencies multiple times, so I don't think that's where the issue lies.
webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./public/index.jsx'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
resolve: {
root: __dirname,
alias: {
App: 'public/components/App.jsx',
Home: 'public/components/Home.jsx',
Footer: 'public/components/Footer.jsx',
Inventory: 'public/components/Inventory.jsx',
Login: 'public/components/nav/Login.jsx',
Navbar: 'public/components/nav/Navbar.jsx',
ProductSearch: 'public/components/Product-Search.jsx',
SingleProduct: 'public/components/Single-Product.jsx',
Product: 'public/components/Product.jsx',
Signup: 'public/components/Signup.jsx',
LandingNavbar: 'public/components/nav/LandingNavbar.jsx',
ProductSearch: 'public/components/ProductSearch.jsx',
Examples: 'public/components/Examples.jsx',
Pricing: 'public/components/Pricing.jsx',
Profile: 'public/components/Profile.jsx',
Checkout: 'public/components/Checkout.jsx',
Receipt: 'public/components/Receipt.jsx',
RequireAuth: 'public/components/auth/require_auth.jsx',
Signout: 'public/components/Signout.jsx',
Tour: 'public/components/tour/Tour.jsx',
BusinessTypes: 'public/components/tour/BusinessTypes.jsx',
Customers: 'public/components/tour/Customers.jsx',
Features: 'public/components/tour/Features.jsx',
GettingStarted: 'public/components/tour/GettingStarted.jsx',
MultiStore: 'public/components/tour/MultiStore.jsx',
Support: 'public/components/tour/Support.jsx',
Actions: 'public/actions/index.js'
},
extensions: ['', '.js', '.jsx']
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
module: {
loaders: [{
test: /\.jsx$/,
loaders: ['react-hot','babel-loader', 'babel?presets[]=es2015,presets[]=stage-0,presets[]=react'],
include: path.join(__dirname, 'public')
}]
}
};
You have the babel loader twice. Just remove 'babel-loader' from your array of loaders. This is because "babel?..." is calling the loader already.
Your package.json must have babel-loader in it. So make sure you run:
npm install babel-loader babel-core babel-preset-es2015 babel-preset-react babel-preset-stage-0 --save-dev
Then this in your webpack config file:
module: {
loaders: [{
test: /\.jsx$/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'stage-0', 'react']
},
include: path.join(__dirname, 'public')
}]
}
If that works, then try adding 'react-hot' to your list of loaders.
What file gives you this error? public/actions/index.js? You are not passing your .js files to babel.
And you are calling babel-loader twice. First as "babel-loader" without any preset and second as "babel" with presets.
Correct loaders would be:
loaders: [{
test: /\.jsx?$/,
loaders: ['react-hot', 'babel?presets[]=es2015,presets[]=stage-0,presets[]=react'],
include: path.join(__dirname, 'public')
}]
Note changed test regexp. Now it covers .js and .jsx files. And I suggest moving presets into .babelrc file
As I write webpack.config.js like this
module.exports = {
entry: './index.jsx',
output: {
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'react']
}
}]
}
};
And in index.jsx I import a react module App
import React from 'react';
import { render } from 'react-dom';
import App from './containers/App';
let rootElement = document.getElementById('box')
render(
<App />,
rootElement
)
I find if I named module app in App.jsx, then webpack will say in index.jsx can't find module App, but if I named named module app in App.js, it will find this module and work well.
So, I'm confuse about it. In my webpack.config.js, I have writed test: /\.jsx?$/ to check file, but why named *.jsx can't be found?
Webpack doesn't know to resolve .jsx files implicitly. You can specify a file extension in your app (import App from './containers/App.jsx';). Your current loader test says to use the babel loader when you explicitly import a file with the jsx extension.
or, you can include .jsx in the extensions that webpack should resolve without explicit declaration:
module.exports = {
entry: './index.jsx',
output: {
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'react']
}
}]
},
resolve: {
extensions: ['', '.js', '.jsx'],
}
};
For Webpack 2, leave off the empty extension.
resolve: {
extensions: ['.js', '.jsx']
}
In the interest of readability and copy-paste coding. Here is the webpack 4 answer from mr rogers comment in this thread.
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
resolve: {
extensions: [".js", ".jsx"]
},
use: {
loader: "babel-loader"
}
},
]
}
Adding to the above answer,
The resolve property is where you have to add all the file types you are using in your application.
Suppose you want to use .jsx or .es6 files; you can happily include them here and webpack will resolve them:
resolve: {
extensions: ["", ".js", ".jsx", ".es6"]
}
If you add the extensions in the resolve property, you can remove them from the import statement:
import Hello from './hello'; // Extensions removed
import World from './world';
Other scenarios like if you want coffee script to be detected you should configure your test property as well like:
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /\.coffee$/, loader: 'coffee-loader' },
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
},
resolve: {
// you can now require('file') instead of require('file.coffee')
extensions: ['', '.js', '.json', '.coffee']
}
};
As mentioned in the comments on the answer from #max, for webpack 4, I found that I needed to put this in one of the rules that were listed under module, like so:
{
module: {
rules: [
{
test: /\.jsx?$/,
resolve: {
extensions: [".js", ".jsx"]
},
include: ...
}
]
}
}
Verify, that bundle.js is being generated without errors (check the Task Runner Log).
I was getting 'can't find module if file named jsx' due to the syntax error in html in component render function.
I was facing similar issue, and was able to resolve using resolve property.
const path = require('path');
module.exports = {
entry: './src/app.jsx',
output: {
path: path.join(__dirname,'public'),
filename: 'bundle.js'
},
module : {
rules: [{
loader: 'babel-loader',
test: /\.jsx$/,
exclude: /node_modules/
}]
},
resolve: {
extensions: ['.js', '.jsx']
}
}
As You can see I have used .jsx in there which resolved following error
ERROR in ./src/app.jsx
Module not found: Error: Can't resolve
For Reference: https://webpack.js.org/configuration/resolve/#resolve-extensions
I faced similar issue with imports while building my typescript project having the following webpack dependencies:
"webpack": "^5.28.0",
"webpack-cli": "^4.5.0"
So, I had a App.tsx file present in the correct path and exported with named export. But, yarn build was failing with Module not found: Error: Can't resolve './App' in '/app/sample_proj/src'. The relevant code for this error is: import {App} from './App';. To fix this, I had to add .tsx under webpack known extensions. Sample entry from webpack.config.js is :
module.exports = {
......
resolve: {
extensions: [ '.ts', '.js', '.tsx', '.jsx'],
}
}
Also, for this error, it does not matter, if the imports are default or named. webpack only needs to know the kind of file extensions it should deal with.
I found restarting my server fixed this issue. simply run
npm start
I'm trying to setup a React project with react-css-modules, webpack and Hot Module Replacement. Everything is working like a charm but I can't get the CSS sourcemaps to work.
I followed this guide to make HMR work. It involves a BrowserSync setup to update the css file after Webpack writes it to disk.
I use (as suggested by react-css-modules) the ExtractTextPlugin to extract all of the css:
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style','css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass')
}
But if I change this to sourcemaps, as suggested here
loader: ExtractTextPlugin.extract('style', 'css?sourceMap!sass-loader outputStyle=expanded&sourceMap=true&sourceMapContents=true')
I get the error: "root" CSS module is undefined. in my browser console.
You can find my example repo here, but here's the full webpack config I'm using for development.
var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var WriteFilePlugin = require('write-file-webpack-plugin').default;
module.exports = {
entry: {
bundle: [
'webpack/hot/dev-server',
'webpack-hot-middleware/client',
'./index.js'
]
},
devtool: 'cheap-module-source-map',
debug: true,
devServer: devServer,
context: path.resolve(__dirname, './src'),
output: {
path: path.resolve(__dirname, './builds'),
filename: '[name].js',
publicPath: '/builds/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.OldWatchingPlugin(),
new WriteFilePlugin(),
new ExtractTextPlugin('[name].css', {
allChunks: true
})
],
module: {
loaders: [
{
test: /\.js$/,
loaders: ['react-hot', 'babel-loader'],
exclude: /node_modules/
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style','css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass')
}
]
},
resolve: {
extensions: ['', '.js', '.json']
}
};
How to make the sourcemap work?
Use this:
ExtractTextPlugin.extract('style','css?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass?sourceMap')
i.e. add the sourceMap param to both css & sass loaders. It said so in sass-loader docs.
This is how I have my css modules set up:
'css-loader?modules&sourceMap&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!',