I know there are about 1000 of these here on SO, but they all seem to reference problem with using the npm package manger and node_modules. My file structure (for the relevant files) is like this:
app
|
main.js
|
src
|
home
|
home.jsx
My main.js file is requiring the home.jsx file like this import Home from './src/home/home.jsx';
I have no idea as to why this would be a problem. I checked for extra spaces that I might have had on t he end of "home.jsx," but that wasn't it. This seems so simple, but I cannot for the life of me understand why this is happening.
If it matters at all, I am using webpack to bundle my files.
//webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './main.js',
output: { path: __dirname, filename: 'bundle.js' },
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
},
resolve: {
extensions: ['', '.js', '.jsx']
}
};
Related
I'm working on an outlook addin I have an express server running. I am setting webpack because I need to transpile js to es5 to make it work in Outlook Desktop. Here is the simplified project structure.
/public
/javascripts
ssoAuth.js
/addin
/commmands
commands.js
commands.html
/server
/bin
/helpers
app.js
The public folder is set as a static folder in my express server
app.use(express.static(path.join(__dirname, '../public'),
My problem is in commands.js I import ssoAuth.js with es6 module import with relative path :
import getGraphAccessToken from "/javascripts/ssoAuthES6.js";
It works fine when I run node ./server/app.js and load my outlook addin, but when I want to use Webpack to bundle, the import is not working, I get :
ERROR in ./addin/commands/commands.js
Module not found: Error: Can't resolve '/javascripts/ssoAuth.js'
I can't figure out how to configure webpack to allow the imports from the public folder.
Here are my webpack config files :
webpack.config.js :
const config = {
devtool: "source-map",
entry: {
polyfill: "#babel/polyfill",
commands: "./addin/commands/commands.js"
},
resolve: {
extensions: [".ts", ".tsx", ".html", ".js"]
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env"]
}
}
},
{
test: /\.html$/,
exclude: /node_modules/,
use: "html-loader"
},
{
test: /\.(png|jpg|jpeg|gif)$/,
use: "file-loader"
}
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
filename: "commands.html",
template: "./addin/commands/commands.html",
chunks: ["polyfill", "commands"]
})
]};
webpack.server.config.js :
return ({
entry: {
server: './server/bin/www',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
__dirname: false,
__filename: false,
},
externals: [nodeExternals()],
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
},
plugins: [
new CopyWebpackPlugin([
{
to: "./public",
from: "./public"
}
])
]})
Can you help figure this out ? Is there a better folder structure that I should use to make it work ?
Thanks
You're using an absolute path
import getGraphAccessToken from "/javascripts/ssoAuthES6.js";
// ^ this will look in your topmost directory on your OS
The relative path, from commands.js, would be:
import getGraphAccessToken from "../../javascripts/ssoAuthES6.js";
Alternatively, you can set Webpack to look for modules from your root directory by adding the following to your webpack configuration:
{
// ...
resolve: {
modules: [path.resolve(__dirname, "src"), "node_modules"],
},
// ...
}
Then you can import from your project's root directory from anywhere, like so:
import getGraphAccessToken from "javascripts/ssoAuthES6.js";
Some other points:
Since you're setting the extensions: [".ts", ".tsx", ".html", ".js"], you don't need to provide file extensions for those imports
You specify .ts and .tsx in your webpack config, but you are using .js files. Consider removing the Typescript extensions
If you are using Typescript, you will need to update import paths in your tsconfig.json
You can consider import path aliases in both Webpack and Typescript to be more explicit that your imports are coming from your project root. Instructions here
I am enhancing a website with ReactJS.
My folder structure looks something like this:
_npm
node_modules
package.json
package-lock.json
webpack.config.js
_resources
js
react
reactapp1.js
reactapp2.js
components
FormDisplay.js
I want to import a custom reactjs package into the FormDisplay component.
When I enter:
import PlacesAutocomplete from 'react-places-autocomplete'
This doesn't work. But if I enter:
import PlacesAutocomplete from "./../../../_npm/node_modules/react-places-autocomplete";
This works. I understand why this is the case. I was wondering if there was a way that I can just enter:
import PlacesAutocomplete from 'react-places-autocomplete';
How do I make it work with just that line of code, without having to find the path to node_modules folder?
My webpack config:
const path = require("path");
const webpack = require("webpack");
const PATHS = {
app: path.join(__dirname, "../_resources/react/"),
build: path.join(__dirname, '../wordpress_site/wp-content/themes/custom_theme/assets/js/'),
};
module.exports = {
entry: {
reactapp1: path.join(PATHS.app, "reactapp1.js"),
reactapp2: path.join(PATHS.app, "reactapp2.js")
},
output: {
filename: "[name].bundle.js",
//path: path.join(__dirname, "dist")
path: PATHS.build
},
module:{
rules: [
{
test: /\.js?$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ["env", "react"],
plugins: ["transform-class-properties"]
}
}
}
]// rules array
}, // module
}
Have you tried using webpack's resolve-modules?
resolve: {
modules: ['_npm/node_modules']
}
Might work
I have code base, the folder structure for which looks like this :
|- build\
|- node_modules\
|- apps\
|--- app_no_1\
|----- index.js
|- src\
|--- modules\
|----- form-login\
|------- Form.jsx
|- package.json
|- webpack.config.js
....
The app_no_1\ folder holds the index file for its React app. However, the modules are sat within the src\ folder. When I import the component from the src directory into the app, I get the error:
bundle.js:41448 Uncaught Error: Module parse failed: Unexpected token (15:18)
You may need an appropriate loader to handle this file type.
| // );
Is there some webpack configuration option I am missing which is required for access to files outside the app's folder? My webpack.config.js is this:
const path = require('path');
const merge = require('merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const PATHS = {
app: path.join(__dirname, 'apps'),
appAthenaTrader: path.join(__dirname, 'apps/athenaTrader'),
appAthenaFinancier: path.join(__dirname, 'apps/athenaFinancier'),
build: path.join(__dirname, 'build'),
modules: path.join(__dirname, 'src/modules')
};
const common = {
output: {
path: PATHS.build,
publicPath: '/',
filename: 'bundle.js'
},
resolve: {
alias: {
modules: PATHS.modules
},
extensions: ['.js', '.jsx', '.json'],
modules: [PATHS.modules, 'node_modules']
},
module: {
rules: [
{
test: /\.jsx?$/,
include: PATHS.app,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
]
},
{
test: /\.scss$/,
include: PATHS.app,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.(jpg|png)$/,
include: PATHS.app,
use: {
loader: 'file-loader?name=[name].[ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'Satoshi Ltd - Athena'
})
]
};
const generateEntry = env => {
const entryVariable = {
entry: {
app: ''
}
};
if (env.app === 'athena-trader') {
entryVariable.entry.app = PATHS.appAthenaTrader;
} else if (env.app === 'athena-financier') {
entryVariable.entry.app = PATHS.appAthenaFinancier;
// } else ...
}
return entryVariable;
};
const devServer = {
devServer: {
stats: 'errors-only',
host: process.env.HOST || 'localhost',
port: process.env.PORT || 3000
},
devtool: 'inline-source-map'
};
const generateConfig = env => {
const entry = generateEntry(env);
if (env.profile === 'development') {
return merge(common, entry, devServer);
}
return merge(common, entry);
};
module.exports = generateConfig(process.env);
I should note that when the folder is brought inside the app_no_1, the app functions fine, i.e. it is able to execute the component & display it. However, the above folder structure is not being accepted for the apps.
The issue is in your babel-loader configuration. Webpack is complaining that it doesn't know how to parse your files (I'm assuming it's JSX).
In your configuration, you have:
module: {
rules: [
{
test: /\.jsx?$/,
include: PATHS.app,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
]
},
// ...
]
include tells webpack to use babel-loader on any files located inside PATHS.app. When it looks at your files located in PATHS.modules, it doesn't use babel-loader. This is when webpack shows that Module parse failed error.
To fix this, you can update your include value to something like this:
include: [PATHS.app, PATHS.modules]
An alternative is to use exclude instead of include.
// assuming you want to only ignore node_modules
exclude: /node_modules/
I also made a barebones example of this on Github.
I have an app that is in a different folder structure than the modules installed from the package.json and I cannot find a way to make it work:
Structure:
includes
build
build stuff
src
shared assets
js
...APP (the app is a few folders down still)
How can I specify that the modules are somewhere and the app is in another place? Is this even possible? as If I set up the src of my app in the place where the build setup is, everything work as expected.
Where is my very simple webpack config.
var getters = require('./../gulpfile.js/config/getters');
var path = require('path');
var appRoot = path.resolve(__dirname, '../src');
var appRoot2 = path.resolve(__dirname, '../../main/jcr_root/etc/designs/fit/includes/shared_assets/js/vueapps/chat_app/src');
module.exports = {
context: appRoot2,
entry: './main.js',
output: {
filename: 'app.js',
path: getters.js.vue.apps.chatapp.dist
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue-loader',
exclude: /node_modules/
},
{
test: /\.js$/,
loaders: 'babel-loader',
exclude: /node_modules/
}
]
},
resolve: {
modules: [
'node_modules'
]
}
};
I this you can see I have appRoot and appRoot2, appRoot works as expected, appRoot2 fails giving me this error.
ERROR in Entry module not found: Error: Can't resolve 'babel-loader' in ...
EDIT: Forgot to mention I'm using :
"vue-loader": "^9.4.0".
"webpack": "^2.2.0".
"babel-loader": "^6.3.2".
EDIT2: Got it working, had to specify with another option:
resolveLoader: {
modules: [
nodeRoot
],
}
Also in the loader had to add this option:
{
test: /\.js$/,
loaders: 'babel',
exclude: /node_modules/,
query: {
presets: [nodeRoot + '/babel-preset-es2015'],
}
}
With the path to the preset.
I am facing this problem :
First, I am starting webpack to build the project. On localhost, everything works fine. In the build folder, index.html and index.js are getting built.
But, when I run it in the browser (not using local server) but using these files, it appears "not found".
Checked webpack.config.js - everything is placed in a single index.js.
This is webpack.config.js:
var path = require('path');
module.exports = {
entry: './entry.js',
output: {
filename: 'build/index.js',
publicPath: '/build'
},
resolve: {
extensions: ['', '.js', '.jsx', '.json']
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
include: path.resolve(__dirname, "app"),
query: {
presets:['react', 'es2015', 'stage-0']
}
},
{
test: /\.scss$/,
loader: 'style-loader!css-loader!sass-loader'
}
]
}
};
There is no eror. But there is text "Not found"