If I add .jsx to require('./StringOption') it works but I thought the resolve section of my webpack.config.js is supposed to allow me to require with no extension. What am I doing wrong?
Also why do I need ./ infront when it resides in the same directory as index.jsx?
Error message after running webpack:
ERROR in ./src/index.jsx
Module not found: Error: Cannot resolve module 'StringOption' in /Users/Mike/packages/chrome-extension-options/src
# ./src/index.jsx 5:19-42
index.js:
'use strict'
var React = require('react')
var ReactDOM = require('react-dom')
var StringOption = require('./StringOption');
ReactDOM.render(<StringOption id="test" name="Test" />, document.getElementById('content'))
webpack.config.js file:
var path = require("path");
module.exports = {
entry: './src/index.jsx',
output: {
path: path.resolve(__dirname, "dist"),
filename: 'index.js'
},
module: {
loaders: [
{
test: /\.jsx$/,
loader: 'jsx-loader',
exclude: /node_modules/
}
]
},
externals: {
'react': 'React',
'react-dom': 'ReactDOM'
},
resolve: {
extensions: ['', '*.js', '*.jsx']
}
};
Directory structure:
- src/
- index.jsx
- StringOption.jsx
- dist/
- index.js
- react.js
- react-dom.js
First of all ./StringOption says that it should search in the same directory. Unlike other places we need to specify from where we need to import a file in react jsx.
Secondly,
In resolve you need not use resolve explicitly, just use babel-loader or else use resolve as
resolve: {
extensions: ['', '.js', '.jsx']
}
or
module: {
loaders: [
{
test: /\.jsx$/,
loader: 'babel-loader',
exclude: /node_modules/
}
]
}
include the following in your webpack.config.js so that you need not to worry about js and jsx extension.
loaders: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
// include: __dirname + '/src',
include: path.join(__dirname, '/src'),
loader: 'babel-loader',
query: {
presets: ['react','es2015']
}
}]
Related
I am building a component library and I am using Webpack to bundle it. Some components only rely on html templates, css and JavaScript that I've written, but some components require external libraries.
What I'd like to achieve is a vendor.js that is optional to include if the component you want to use needs it.
For instance, If a user only needs a component without vendor dependencies, it would suffice that they use main.bundle.js which only contains my own code.
In my index.js, I have the following imports:
import { Header } from './components/header/header.component';
import { Logotype } from './components/logotype/logotype.component';
import { Card } from './components/card/card.component';
import { NavigationCard } from './components/navigation-card/navigation-card.component';
import { AbstractComponent } from './components/base/component.abstract';
import { Configuration } from './system.config';
import 'bootstrap-table';
import './scss/base.scss';
All of these imports are my own, expect for bootstrap-table.
I have configured Webpack like this:
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractScss = new ExtractTextPlugin({
filename: "[name].bundle.css"
});
module.exports = {
entry: {
main: './src/index.ts'
},
output: {
path: path.resolve(__dirname, 'dist/release'),
filename: "[name].bundle.js",
chunkFilename: "[name].bundle.js"
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor', // Specify the common bundle's name.
minChunks: function (module) {
// Here I would like to tell Webpack to give
// each bundle the ability to run independently
return module.context && module.context.indexOf('node_modules') >= 0;
}
}),
extractScss
],
devtool: "source-map",
resolve: {
// Add `.ts` as a resolvable extension.
extensions: ['.webpack.js', '.web.js', '.ts', '.js', '.ejs']
},
module: {
rules: [
// All files with a '.ts' extension will be handled by 'awesome-typescript-loader'.
{ test: /\.ts?$/, exclude: /node_modules/, loader: "awesome-typescript-loader" },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" },
// Allows for templates in separate ejs files
{test: /\.ejs$/, loader: 'ejs-compiled-loader'},
{
test: /\.scss$/,
use: extractScss.extract({
use: [{
loader: 'css-loader', options: {
sourceMap: true
}
}, {
loader: 'sass-loader', options: {
soureMap: true
}
}]
})}
]
}
}
This results in two .js files and one .css. However, webpacks common module loading functionality resides in vendor.js, and that renders my main unusable if I don't include vendor first, and it isn't always needed.
To sum it up, if a user only needs the footer (no external dependencies), this would suffice:
<script src="main.bundle.js"></script>
If the user wants to use the table, which has an external dependency, they would need to include both:
<script src="vendor.js"></script>
<script src="main.bundle.js"></script>
Right now, including only main.bundle.js gives me this error:
Uncaught ReferenceError: webpackJsonp is not defined.
I am aware that I can extract all common functionality by adding this after my vendor chunk is created in the Webpack config:
new webpack.optimize.CommonsChunkPlugin({
name: 'common'
})
But this approach still requires the user to include two .js files.
How can I go about achieving this? It seems that it only differs 2 kb when I don't extract the common modules like I do above, and that is fine with me.
Turns out this is very easy to do if you can stand some manual work and actually understand what Webpack does (which I didn't). I solved it like this:
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractScss = new ExtractTextPlugin({
filename: "[name].bundle.css"
});
module.exports = {
entry: {
main: './src/index.ts',
vendor: './src/vendor/vendor.ts'
},
output: {
path: path.resolve(__dirname, 'dist/release'),
filename: "[name].bundle.js",
chunkFilename: "[name].bundle.js"
},
plugins: [
extractScss
],
devtool: "source-map",
resolve: {
// Add `.ts` as a resolvable extension.
extensions: ['.webpack.js', '.web.js', '.ts', '.js', '.ejs']
},
module: {
rules: [
// All files with a '.ts' extension will be handled by 'awesome-typescript-loader'.
{ test: /\.ts?$/, exclude: /node_modules/, loader: "awesome-typescript-loader" },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" },
// Allows for templates in separate ejs files
{test: /\.ejs$/, loader: 'ejs-compiled-loader'},
{
test: /\.scss$/,
use: extractScss.extract({
use: [{
loader: 'css-loader', options: {
sourceMap: true
}
}, {
loader: 'sass-loader', options: {
soureMap: true
}
}]
})}
]
}
}
In vendor.ts, I then simply import any vendor dependencies I have:
import 'jquery';
import 'bootstrap-table';
This results in two different files, both have Webpacks bootstrapping logic.
Hope this helps someone.
I started a new Vuetify / Webpack project, and tried to implement vue-router after setting up a project via vue init vuetify/webpack.
I set up the router based on the instructions from this tutorial. After some fiddling, I got it working by changing the way I imported Vue components.
In my router/index.js file:
// works for me
import Main from '../components/Main.vue'
// does NOT work; from the tutorial
import Main from '#/components/Main'
My question is, why do I have to import my Main.vue file relatively and include the .vue extension on the import?
My project structure:
-node_modules/
-public/
-src/
|-components/
||-Main.vue
|-router/
||-index.js
|-App.vue
|main.js
-index.html
-package.json
-webpack.config.js
My webpack.config.js file:
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
resolve: {
alias: {
'public': path.resolve(__dirname, './public')
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
objectAssign: 'Object.assign'
}
},
{
test: /\.styl$/,
loader: ['style-loader', 'css-loader', 'stylus-loader']
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
devServer: {
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
You are attempting to load a file from an alias directory named #. But in your webpack config file, you haven't defined that alias.
Also, you are required to specify the .vue extension because you haven't added it to the resolvable extensions in the resolve property in your config object.
In your webpack.config.js file, add a list of extensions to resolve and an alias called # which maps to your src directory:
resolve: {
extensions: ['', '.js', '.vue'],
alias: {
'#': path.resolve(__dirname, './src'),
...
}
...
}
Edit: #evetterdrake informed me that when using vue-cli to set up a project with Vuetify, the resolve config property is positioned after the module property, which is different than when setting up a normal Webpack project.
Be sure to add these config options to the existing resolve property or it will be overwritten and ignored.
I am working on a project that integrates react, redux, and firebase. react-redux-firebase seems to be a convenient tool. However, the code is not being complied successfully. Below is the error, webpack.config.js, .babelrc, and index.js. Thanks for help in advance.
Error message:
ERROR in ./~/react-redux-firebase/src/connect.js
Module parse failed:
/Users/xiqianglin/ucsdflyers/node_modules/react-redux-firebase/src/connect.js
Unexpected token (43:24) You may need an appropriate loader to handle this file type.
| }
|
| static contextTypes = {
| store: PropTypes.object.isRequired
| };
# ./~/react-redux-firebase/src/index.js 1:0-31 # ./src/index.js # multi ./src/index.js
/****And there are other similar errors, all "...appropriate loader..." ***/
webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/src/index.html',
filename: 'index.html',
inject: 'body'
});
module.exports = {
entry: [
'./src/index.js'
],
module: {
loaders: [
{test: /\.js$/,
exclude: /node_modules/,
loader:'babel-loader'}
]
},
resolve: {
extensions: [".js", ".jsx", ".es6"]
},
output: {
filename: "index_bundle.js",
path: __dirname + '/dist'
},
plugins: [HTMLWebpackPluginConfig]
};
.babelrc
{
"presets": ["react", "es2015"]
}
index.js
/*Other Imports...*/
import { firebaseStateReducer } from 'react-redux-firebase'; //This is the line causing error
ReactDOM.render(
<Provider>
<App/>
</Provider>,
documeng.getElementById('app')
)
Duble check that you npm install-ed all your dependencies.
Then if that doesn't work, try this:
npm install babel-preset-es2015
and add the a query for es2015 after your exclude
{
test: /\.js$/,
exclude: /node_modules/,
loader:'babel-loader',
query: {
presets: ['es2015']
}
}
If you need to include a specific node module, try including your source directory and that specific node module folder to be parsed by babel-loader.
So instead of the exclude: /node_modules/, try
include: [
path.resolve(__dirname, "src"),
path.resolve(__dirname, "node_modules/react-redux-firebase")
]
I am trying to include sequence.js in my index.js file and I get the following error:
ERROR in ./src/js/sequence.js Module not found: Error: Cannot resolve
module 'imagesLoaded' in /home/jdellaria/Desktop/Musicpack/src/js #
./src/js/sequence.js 1144:95-143
ERROR in ./src/js/sequence.js Module not found: Error: Cannot resolve
module 'Hammer' in /home/jdellaria/Desktop/Musicpack/src/js #
./src/js/sequence.js 1144:95-143 Here is my Configuration
webpack.config.js
// var webpack = require('webpack');
var path = require('path');
// webpack.config.js
var config = {
entry: './src',
resolve: {
root: path.resolve('./src'),
extenstions: ['', '.js'],
moduleDirectories: ['node_modules']
},
output: {
path: './dist',
filename: 'my-app.js'
},
externals:[
require('webpack-require-http')
],
module:
{
loaders:
[
{ test: /\.css$/, loaders: ['style', 'css'] }, // Note that the order is important here, it means that 'style-loader' will be applied to the ouput of 'css-loader'
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/, query: {presets: ['es2015']}},
// { test: /\.js$/, loaders: ['babel'] }, // note that specifying 'babel' or 'babel-loader' is equivalent for Webpack
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&minetype=application/font-woff" },
{ test: /\.(jpe?g|png|gif|svg)$/, loader: 'url-loader?limit=10000&name=[path][name].[ext]'},
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }
]
}
}
module.exports = config;
index.js
require("!style!css!./css/styley.css");
require("./js/sequence.js");
console.log('Hello Webpack!');
document.write("It works.");
var greet = require('./greet'); // Import the greet function
greet('Webpack Jon');
index.html
<html>
<head>
<script type="text/javascript" src="./dist/my-app.js"></script>
</head>
<body>
</body>
</html>
Sequence.js uses AMD modules, and its looking to resolve those in the node_modules directory. Instead of referencing script directly in the /js folder, install it as a node module:
npm install sequencejs
Then require it like this in your index.js
require("sequencejs");
I have this webpack.config.js:
module.exports = {
entry: './src/admin/client/index.jsx',
output: {
filename: './src/admin/client/static/js/app.js'
},
loaders: [
{
test: /\.jsx?$/,
loader: 'babel',
exclude: /node_modules/,
query: {
optional: ['runtime']
}
}
],
resolve: {
extensions: ['', '.js', '.jsx']
}
};
...yet I still get this error:
$ webpack -v
Hash: 2a9a40224beb025cb433
Version: webpack 1.10.5
Time: 44ms
[0] ./src/admin/client/index.jsx 0 bytes [built] [failed]
ERROR in ./src/admin/client/index.jsx
Module parse failed: /project/src/admin/client/index.jsx Line 1: Unexpected reserved word
You may need an appropriate loader to handle this file type.
| import React from 'react';
| import AdminInterface from './components/AdminInterface';
I have:
Installed webpack globally and locally
Installed babel-loader, babel-core, and babel-runtime
Installed babel-loader globally, just in case
Why the hell is webpack seemingly ignoring babel-loader? Or does babel-loader not work with modules?
Update:
It looks like babel handles the input file just fine. When I run:
./node_modules/babel/bin/babel.js ./src/admin/client/index.jsx
...it outputs ES5 as expected. Therefore, it seems to me like somehow webpack isn't properly loading babel-loader.
This looks like a case of operator error. My webpack.config.js structure was not correct. Specifically, I needed to put the loader details inside of a module section:
module.exports = {
entry: './src/admin/client/index.jsx',
output: {
filename: './src/admin/client/static/js/app.js'
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel',
exclude: /node_modules/,
query: {
optional: ['runtime']
}
}
],
resolve: {
extensions: ['', '.js', '.jsx']
}
}
};
I fixed the same problem by including the es2015 and react presets and then adding them to the webpack.config.js file.
npm install --save-dev babel-preset-es2015
npm install --save-dev babel-preset-react
as explained in this post: https://www.twilio.com/blog/2015/08/setting-up-react-for-es6-with-webpack-and-babel-2.html
my full webpack.config.js file:
module.exports = {
context: __dirname + "/src",
entry: './main',
output: {
path: __dirname + "/build",
filename: "bundle.js"
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
query: {
presets: ['es2015', 'react']
}
}
],
resolve: {
extensions: ['.js', '.jsx']
}
}
};
What is the version of your babel?If babel version is up to 6+.You need to identify the preset 'es2015' and 'react' like this
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel', // 'babel-loader' is also a legal name to reference
query: {
presets: ['react', 'es2015']
}
}
]
}
Don't forget to install these modules:
npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev