Webpack2 can't resolve file in pathname - reactjs

I have having a strange issue I can't seem to resolve.
I am getting this error:
Error: Can't resolve 'store/configureStore' in '/Users/samboy/company/oh-frontend/app'
My webpack file looks like this:
name: 'browser',
context: path.join(__dirname, '..', '..', '..', 'app'),
entry: {
app: './client'
},
output: {
// The output directory as absolute path
path: assetsPath,
// The filename of the entry chunk as relative path inside the output.path directory
filename: '[name].js',
// The output path from the view of the Javascript
publicPath: publicPath
},
module: {
loaders: commonLoaders
},
resolve: {
modules: [
path.resolve(__dirname, '..', '..', '..', 'app'),
'node_modules'
],
extensions: ['', '.js', '.jsx', '.css']
},
plugins: [
// extract inline css from modules into separate files
new ExtractTextPlugin('styles/bundled-modules.css'),
// files in global directory should be concatenated into one file for prod
new CopyWebpackPlugin([
{ from: 'fonts/', to: 'fonts/' }
, { from: '_web/css/global/fonts.css', to: 'styles/fonts.css' }
, { from: '_web/css/vendors', to: 'styles/vendors' }
]),
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false
}
}),
new webpack.DefinePlugin({
__DEVCLIENT__: false,
__DEVSERVER__: false,
__PLATFORM_WEB__: true,
__PLATFORM_IOS__: false
}),
new InlineEnviromentVariablesPlugin({ NODE_ENV: 'production' }),function()
{
this.plugin("done", function(stats)
{
if (stats.compilation.errors && stats.compilation.errors.length)
{
console.log(stats.compilation.errors);
process.exit(1);
}
// ...
});
}
],
postcss: postCSSConfig
}
The file is certainly present in that folder. It worked fine with webpack. It doesn't seem to work with webpack2 though.

I'm guessing because you didn't post your app file, but can you change the import statement in the app file to "./store/configureStore"?

Related

Cannot load JSON files in React with webpack 5

Summarize the problem
I created a webpack react boilerplate for my projects and it works fine except it cannot handle JSON files and according to webpack documentation:
⚠️ Since webpack >= v2.0.0, importing of JSON files will work by default. You might still want to use this if you use a custom file extension. See the v1.0.0 -> v2.0.0 Migration Guide for more information
Describe what you’ve tried
Here's my webpack common setup:
const path = require('path'),
//used to check if the given file exists
fs = require('fs'),
//dotenv
dotenv = require('dotenv'),
//plugins
{ DefinePlugin } = require('webpack'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
MiniCssExtractPlugin = require('mini-css-extract-plugin'),
EsLintPlugin = require('eslint-webpack-plugin'),
//constants
{
port,
devServer,
jsSubDirectory,
isCssModules,
metaInfo: { title, description, url, keywords },
} = require('./constants'),
PATHS = require('./paths'),
fullDevServerUrl = `${devServer}:${port}`;
module.exports = (env, options) => {
// the mode variable is passed in package.json scripts (development, production)
const isDevelopment = options.mode === 'development',
/*================ setup environments variables ===================*/
// create a fallback path (the production .env)
basePath = `${PATHS.environments}/.env`,
// concatenate the environment name to the base path to specify the correct env file!
envPath = `${basePath}.${options.mode}`,
// check if the file exists, otherwise fall back to the production .env
finalPath = fs.existsSync(envPath) ? envPath : basePath,
// set the path parameter in the dotenv config
fileEnv = dotenv.config({ path: finalPath }).parsed,
// create an object from the current env file with all keys
envKeys = Object.keys(fileEnv).reduce((prev, next) => {
prev[`process.env.${next}`] = JSON.stringify(fileEnv[next]);
return prev;
}, {});
/*================ finish setup environments variables ===================*/
return {
entry: `${PATHS.src}/index.js`,
output: {
// __dirname is the absolute path to the root directory of our app
path: PATHS.outputSrc,
// hashes are very important in production for caching purposes
filename: jsSubDirectory + 'bundle.[contenthash:8].js',
// used for the lazy loaded component
chunkFilename: jsSubDirectory + '[name].[contenthash:8].js',
publicPath: '/',
assetModuleFilename: (pathData) => {
//allows us to have the same folder structure of assets as we have it in /src
const filepath = path.dirname(pathData.filename).split('/').slice(1).join('/');
return `${filepath}/[name].[hash][ext][query]`;
},
},
optimization: {
// used to avoid duplicated dependencies from node modules
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
enforce: true,
chunks: 'all',
},
},
},
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
// declaring alias for reducing the use of relative path
alias: {
'#/js': `${PATHS.src}/js`,
'#/scss': `${PATHS.src}/scss`,
'#/img': `${PATHS.src}/assets/images`,
'#/jest': PATHS.jest,
},
},
module: {
rules: [
{
test: /\.js|jsx$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: { cacheDirectory: true },
},
},
{
test: /\.(jpe?g|svg|png|gif|ico|eot|ttf|woff2?)(\?v=\d+\.\d+\.\d+)?$/i,
type: 'asset/resource',
},
{
test: /\.s?[ac]ss$/,
//removed (exclude: /node_modules/) to enable using external styles
use: [
{
// style-loader => insert styles in the head of the HTML as style tags or in blob links
// MiniCssExtractPlugin => extract styles to a file
loader: isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader,
//if source map is set to true from previous loaders => this loader will be true as well
},
{
//Resolves #import statements
loader: 'css-loader',
options: {
// used for debugging the app (to see from which component styles are applied)
sourceMap: isDevelopment,
// Number of loaders applied before CSS loader (which is postcss-loader)
importLoaders: 3,
// the following is used to enable CSS modules
...(isCssModules
? {
modules: {
//exclude external styles from css modules transformation
auto: (resourcePath) => !resourcePath.includes('node_modules'),
mode: (resourcePath) => {
if (/global.scss$/i.test(resourcePath)) {
return 'global';
}
return 'local';
},
localIdentName: isDevelopment ? '[name]_[local]' : '[contenthash:base64]',
localIdentContext: PATHS.src,
localIdentHashSalt: 'react-boilerplate',
exportLocalsConvention: 'camelCaseOnly',
},
}
: {}),
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
ident: 'postcss',
plugins: [
'postcss-flexbugs-fixes',
[
'postcss-preset-env',
{
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
},
],
// Adds PostCSS Normalize as the reset css with default options,
// so that it honors browserslist config in package.json
// which in turn let's users customize the target behavior as per their needs.
'postcss-normalize',
],
},
sourceMap: isDevelopment,
},
},
{
//Rewrites relative paths in url() statements based on the original source file
loader: 'resolve-url-loader',
options: {
//needs sourcemaps to resolve urls (images)
sourceMap: true,
},
},
{
//Compiles Sass to CSS
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
],
},
plugins: [
new EsLintPlugin({
extensions: ['.js', '.jsx', '.json'],
}),
new HtmlWebpackPlugin({
title,
template: `${PATHS.src}/index.html`,
filename: 'index.html',
inject: 'body',
favicon: `${PATHS.src}/assets/images/favicon.png`,
meta: {
description,
keywords,
url: isDevelopment ? fullDevServerUrl : url,
'apple-mobile-web-app-capable': 'yes',
'mobile-web-app-capable': 'yes',
},
}),
new DefinePlugin(envKeys),
],
};
};
Here's the link of the repository:
https://github.com/react-custom-projects/webpack-react-boilerplate
Fixed using the following steps:
webpack.common.js:
json files was going through babel-loader because my regular expression for js and jsx was wrong. This is the correct regular expression:
test: /\.(js|jsx)$/,
eslintrc.js:
ignore json files:
ignorePatterns: ['**/src/**/*.json'],

How to include node_modules using webpack?

In my angularJs 1.3 application, earlier I was using bower and grunt and it was working fine. I was adding files in my index.html like the following screenshot. But now I have installed all the packages using NPM and using WEbPack 4.21.0 for bundling and run the application. But now if I remove the packages link from Index.html file my application stops working. But I don't want all those links in Index.html and just want to generate a bundle file from those files. Kindly guide me how can I achieve this? Currently, its just adding angular.js file and few other files in vendor.js.
Index.html
Package.json
webpack.config.js
Updated Question:
Now i am using following webpack.config.js but its creating bootstrap_and_some_plugin.css.js . It has to create css file but don't know why it's creating js file?
module.exports = {
context: __dirname + '/app/scripts',
resolve: {
modules: ['bower_components', 'node_modules'],
alias: {
bower_components: __dirname + '/app/bower_components',
assets: __dirname + '/app/assets'
},
extensions: ['.js', '.jsx', '.css']
},
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" }
]
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}]
}
]
},
entry: {
app: './main-app.js',
'bootstrap_and_some_plugin.css': [
'bower_components/font-awesome/css/font-awesome.css',
'bower_components/seiyria-bootstrap-slider/dist/css/bootstrap-slider.min.css',
'bower_components/angular-ui-tree/dist/angular-ui-tree.min.css',
]
},
output: {
filename: '[name].js',
path: __dirname + '/app/scripts',
//chunkFilename: '[id].[chunkhash].js',
},
devServer: {
contentBase: './app',
host: 'localhost',
port: '9000',
inline: true,
compress: true,
proxy: {
'/api/**': {
//target: 'http://10.189.1.159:8080',
target: 'http://localhost:9100',
secure: false,
changeOrigin: true,
cookieDomainRewrite: true
}
},
open: true
},
plugins: [
]
};
In the file webpack.config.js, you add this property inside the resolve property:
resolve: {
alias: {
bower_components: __dirname + '/app/bower_components'
}
}
In the file main-app.js, if you want to use some js file, you call like this:
require('bower_components/jquery/dist/jquery.js');
require('bower_components/angular/angular.js');
require('bower_components/bootstrap/dist/js/bootstrap.js');
// ...
You need to specify the path of the file webpack.config.js. In my example, all the path looks like:
your_project
webpack.config.js
app
bower_components
jquery
...
angular
...
bootstrap
...
__dirname refers to the current path of the js file which is using it. If you use __dirname inside the webpack.config.js file, it will render your_project. Or using it inside jquery.js, it will render your_project\app\bowser_components\jquery\dist.
Then, build to bundle.js file and delete all the path in the Index.cshtml file.
Hope this helps!
UPDATE: If your js target file goes too big. You can split modules to multiple parts, like this:
entry: {
'bootstrap_and_some_plugin.css': [
'./app/bower_components/bootstrap/dist/css/bootstrap.min.css',
'./app/bower_components/some-plugin/css/some-plugin.css'
],
'jquery_and_angular.js': [
'./app/bower_components/jquery/dist/jquery.js',
'./app/bower_components/angular/angular.js'
],
'site.js': ['./js/site']
}
Then, in your Index.cshtml:
<link href="bootstrap_and_some_plugin.css" rel="stylesheet" />
<!-- body content -->
<script src="jquery_and_angular.js"></script>
<script src="site.js"></script>
UPDATE 2: You need to install the 2 packages babili-webpack-plugin and extract-text-webpack-plugin
In the file webpack.config.js:
// define these variables before "module.exports"
var BabiliPlugin = require('babili-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {...};
Then, setting the pluggin options:
plugins: [
new BabiliPlugin({}, { test: /\.js$/, comments: false }),
new ExtractTextPlugin('[name]'),
... and other options
]
and the output options:
output: {
filename: '[name]',
... and other options
}

Resolving relative paths in React with Webpack not working

I have a react project and I am using webpack. I have a component in frontend/app/components/editor/index.js that I want to include in another component. Currently in order to reference this component I am having to use a relative path (../../../../app/components/editor). However, this is very not easy to use and would like to simply use 'components/editor' for example. My Webpack config file in in fronted/webpack.config.js.
I have added a resolve setting as in this post (Resolving require paths with webpack) but it's still not working.
const {resolve} = require('path');
const path = require('path');
const webpack = require('webpack');
const validate = require('webpack-validator');
const {getIfUtils, removeEmpty} = require('webpack-config-utils');
module.exports = env => {
const {ifProd, ifNotProd} = getIfUtils(env)
return validate({
entry: './index.js',
context: __dirname,
output: {
path: resolve(__dirname, './build'),
filename: 'bundle.js',
publicPath: '/build/',
pathinfo: ifNotProd(),
},
devtool: ifProd('source-map', 'eval'),
devServer: {
port: 8080,
historyApiFallback: true
},
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'},
{test: /\.css$/, loader: 'style-loader!css-loader'},
{test: /(\.eot|\.woff2|\.woff|\.ttf|\.svg)/, loader: 'file-loader'},
],
},
resolve: {
root: path.resolve('./app'),
},
plugins: removeEmpty([
ifProd(new webpack.optimize.DedupePlugin()),
ifProd(new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false,
quiet: true,
})),
ifProd(new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"',
},
})),
ifProd(new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
screw_ie8: true, // eslint-disable-line
warnings: false,
},
})),
])
});
};
These are all the settings I have tried in the resolve block but nothing works.
resolve: {
alias: {
shared: path.resolve(__dirname, 'app')
},
resolve: {
root: path.resolve('./app')
},
resolve: {
modules: ['app']
},
resolve: {
modulesDirectories: ['app']
},
Actually, it has to be
model.exports = env => {
...,
resolve: {
modules: ['app', 'node_modules']
},
...
}
So modules is a property of resolve object which itself is a property of the global configuration object. Also, I have included node_modules, because it's likely you want to refer to those as well after you overwrite the default, which is just [ 'node_modules' ]. See docs for more information.
Update based on comment
You are getting an error from webpack-validator, which is not gonna be maintained because of the inbuilt webpack validator. See more in this SO answer and webpack-validator npm. So the error [1] "modules" is not allowed is incorrect. To fix it you need to remove/uninstall webpack-validator.

Webpack server configuration + external libs

I have the following webpack configuration file:
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const LiveReloadPlugin = require('webpack-livereload-plugin');
const path = require('path');
module.exports = {
entry: [
'webpack-dev-server/client?http://0.0.0.0:2000', // WebpackDevServer host and port
'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
'./app/index.tsx'
],
output: {
path: __dirname + '/dist/',
filename: 'bundle.js'
},
devtool: 'source-map',
resolve: {
extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js']
},
module: {
loaders: [
{
test: /\.tsx?$/,
loaders: ['react-hot', 'ts'],
include: path.join(__dirname, 'app')
}
],
preLoaders: [
'source-map-loader'.
{test: /\.js$/, loader: 'source-map-loader'}
]
},
plugins: [
new CopyWebpackPlugin([
{from: './app/index.html', to: './dist/index.html'}
]),
new webpack.HotModuleReplacementPlugin()
],
builds.
externals: {
'react': 'React',
'react-dom': 'ReactDOM'
}
};
and here is my server configuration:
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const config = require('./webpack.config');
new WebpackDevServer(webpack(config), {
contentBase: './dist',
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true,
open: 'http://localhost:2000'
}).listen(2000, 'localhost', function (err, result) {
if (err) {
return console.log(err);
}
console.log('Listening at http://localhost:2000/');
});
I want to be able to access the application from root path: http://localhost:2000 and not http://localhost:2000/dist.
One more thing, is there any way to move all the external dependancies from node_modules to dist with webpack (without the need to include the script tag in the index.html file)?
First of all for set application start point you need to set publicPath to "/" or publicPath: 'http://localhost:2000'
Your second question
Is there any way to move all the external dependancies from node_modules to dist with webpack?
Yes
You can use different file just for external modules and bundle that file. You don't need to take care of index.html file let webpack plugin HtmlWebpackPlugin take care of it.
First step set entry points for your app
entry: {
'vendors': './src/vendors.ts',//your external libraries
'app': './src/main.ts' //your app
}
and out put
output: {
publicPath: '/',
filename: '[name].js'//this will generate two different files app.js, vendor.js
}
How to add HtmlWebpackPlugin?
Add this in you plugins
new HtmlWebpackPlugin({
template: "./src/index.html",
minify:false
})
Now it will place script tags for you
on you server configuration change your public path to
publicPath: '/',

Specify destination folder in url-loader for webpack

I have images path in css like url(images/image1.jpg) and the loader is defined as
{ test: /\.(png|woff|woff2|eot|ttf|svg|jpg)$/, loader: 'url-loader?limit=1&name=images/[name].[ext]' },
The issue I am facing is that after build process the images are copied to respective folder but the path is pointing to images/image1.jpg relative to the css file location. I want it to be relative to the root directory.
I tried adding a leading / in the name query parameter and it partially fixed the issue
{ test: /\.(png|woff|woff2|eot|ttf|svg|jpg)$/, loader: 'url-loader?limit=1&name=images/[name].[ext]' },
but when I move my files into a sub folder it still points to the root of the domain instead of the folder.
Can you tell me what I am missing in the configuration?
Here is the webpack configuration
'use strict';
var webpack = require('webpack'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
OpenBrowserPlugin = require('open-browser-webpack-plugin'),
ExtractTextPlugin = require('extract-text-webpack-plugin'),
path = require('path'),
srcPath = path.join(__dirname, 'src'),
jsDestPath = 'scripts/';
module.exports = {
target: 'web',
cache: true,
entry: {
common: ['react', 'react-router', 'alt', 'es6-promise'],
offline: path.join(srcPath, 'libs/offline.min.js'),
materialize: path.join(srcPath, 'libs/materialize.js'),
css3_animate_it: path.join(srcPath, 'libs/css3-animate-it.js'),
app: path.join(srcPath, 'App.js')
},
resolve: {
root: srcPath,
extensions: ['', '.js'],
modulesDirectories: ['node_modules']
},
output: {
path: path.join(__dirname, 'build'),
publicPath: '',
filename: jsDestPath + '[name].js',
library: ['Example', '[name]'],
pathInfo: true
},
module: {
loaders: [
{
test: /\.js?$/,
exclude: /node_modules/,
loader: 'babel?cacheDirectory'
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
/*{
test: /\.(png|woff|woff2|eot|ttf|svg|jpg)$/,
loader: 'url-loader?limit=5' // inline base64 URLs for <=8k images, direct URLs for the rest
},*/
{ test: /\.(png|woff|woff2|eot|ttf|svg|jpg)$/, loader: 'url-loader?limit=1&name=images/[name].[ext]' },
{
test: /\.rt/,
loader: "react-templates-loader"
}
],
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
}),
new webpack.optimize.CommonsChunkPlugin('common', jsDestPath + 'common.js'),
new webpack.optimize.UglifyJsPlugin({minimize: true}),
new HtmlWebpackPlugin({
inject: true,
template: 'src/index.html'
}),
new OpenBrowserPlugin({
url: 'http://localhost:8080',
browser: 'Chrome'
}),
new webpack.NoErrorsPlugin(),
new ExtractTextPlugin("styles/style.css", {
allChunks: true
})
],
debug: true,
//devtool: 'eval-source-map',//'eval-cheap-module-source-map',
devServer: {
contentBase: './build',
historyApiFallback: true
}
};
Remove publicPath: '', or set it to publicPath: '/', and require images
like this let imgSrc = require('../../img/image.png'); via relative paths(from where you are trying to require images).
It should get resolved as {publicPath}/images/[name].[ext]
I hope it should work.
You need to prefix your image URL with ~, otherwise it will be treated as relative to the CSS path. The ~ triggers webpack's normal module resolution. More info in the CSS loader docs here.

Resources