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
Related
I want to bundle a JavaScript project by WebPack but there is more problems in none-module libraries because imported them by 'import' capability,ECMAScript 6 module loader run strict mode by default and it tack more errors.
Question :
How can I import none module libraries without strict mode to bundle them by WebPack?
index.js
import '../examples/js/libs/draco/draco_encoder.js';
import './js/libs/codemirror/codemirror.js';
import './js/libs/codemirror/mode/javascript.js';
import './js/libs/codemirror/mode/glsl.js';
...
webpack.config.js
const path = require('path');
const webpack = require('webpack');
// webpack.config.js
module.exports = {
entry: {
polyfills: './editor/polyfills',
index: './lib/index.js',
},
mode: 'development',
output: {
path: __dirname,
publicPath: '/',
filename: './editor/[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
devServer: {
watchContentBase: true,
publicPath: "/",
contentBase: "./",
hot: true,
port: 8080,
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['#babel/preset-env']
}
}
}
]
}
};
babel.config.json
{
"presets": [
"#babel/preset-env"
]
}
I tryed :
babel
esmify
browserify
Shimming in WebPack
...
Thanks for your attention.
Webpack enables use of loaders to preprocess files. This allows you to bundle any static resource way beyond JavaScript.
About loaders: Loaders.
You can easily write your own loaders using Node.js : Writing Loader.
For execute JS script once in global context that can solved my problem : Script Loader
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 trying to make a library of Gatsby components (using specific Gatsby library rather than general React components).
I have been compiling using just babel but I want to be able to translate any CSS-in-JS and do other things so I am trying to build using Webpack.
When I try to compile the Gatsby component it fails in the Gatsby module. I know Gatsby is untranspiled ES6 so I included node_modules in my webpack configuration to transpile but I still:
ERROR in ./node_modules/gatsby/cache-dir/gatsby-browser-entry.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/kylecalica/Code/gatsby-learn/gatsby-components/node_modules/gatsby/cache-dir/gatsby-browser-entry.js: Unexpected token (25:4)
23 |
24 | return (
> 25 | <React.Fragment>
| ^
26 | {finalData && render(finalData)}
27 | {!finalData && <div>Loading (StaticQuery)</div>}
28 | </React.Fragment>
Webpack:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const htmlWebpackPlugin = new HtmlWebpackPlugin({
filename: "index.html"
});
module.exports = {
entry: path.join(__dirname, "/src/index.js"),
output: {
filename: 'main.js',
path: path.resolve(__dirname, "/webpack/dist")
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
]
},
plugins: [htmlWebpackPlugin],
devServer: {
contentBase: path.join(__dirname, "dist"),
port: 9000,
open: true
}
};
I am currently trying to take what Gatsby says to do to Storybook in my code but it's hard to figure out how to translate this from their strange way into mine?
Storybook's way of webpack:
module.exports = ({ config }) => {
// Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
config.module.rules[0].exclude = [/node_modules\/(?!(gatsby)\/)/]
// use installed babel-loader which is v8.0-beta (which is meant to work with #babel/core#7)
config.module.rules[0].use[0].loader = require.resolve("babel-loader")
// use #babel/preset-react for JSX and env (instead of staged presets)
config.module.rules[0].use[0].options.presets = [
require.resolve("#babel/preset-react"),
require.resolve("#babel/preset-env"),
]
config.module.rules[0].use[0].options.plugins = [
// use #babel/plugin-proposal-class-properties for class arrow functions
require.resolve("#babel/plugin-proposal-class-properties"),
// use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
require.resolve("babel-plugin-remove-graphql-queries"),
]
// Prefer Gatsby ES6 entrypoint (module) over commonjs (main) entrypoint
config.resolve.mainFields = ["browser", "module", "main"]
return config
}
.babelrc :
{
"presets": [
"babel-preset-gatsby-package",
"#babel/preset-react",
"#babel/preset-env"
]
}
I solved this by converting what Storybook's webpack module had. I am still putting it through testing however but it compiles fine for now:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const htmlWebpackPlugin = new HtmlWebpackPlugin({
filename: "index.html"
});
module.exports = {
entry: path.join(__dirname, "/src/index.js"),
output: {
filename: 'index.js',
path: path.resolve(__dirname, "webpack")
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: {
loader: "babel-loader",
options: {
presets: ["babel-preset-gatsby-package"],
plugins: ["#babel/plugin-proposal-class-properties"]
},
},
exclude: [/node_modules\/(?!(gatsby)\/)/],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
]
},
plugins: [htmlWebpackPlugin],
devServer: {
contentBase: path.join(__dirname, "dist"),
port: 9000,
open: true
}
};
I'm setting up webpack for a large already existing React App.
Seems to be working fine but some modules causes trouble unless I specifically add the extension to the import
//not working
import AppRouter from './router';
//working but meh
import AppRouter from './router.jsx';
It does not occur in all the relative imports but some for what I see look random.
The error, it occur multiple times for different files
ERROR in ./src/main/resources/js/cs/index.js
Module not found: Error: Can't resolve './router' in '<ommited_path>/src/main/resources/js/cs'
# ./src/main/resources/js/cs/index.js
The folder structure for that file
/src
--/main
--/resources
--/js/
--/cs
index.js
router.jsx
store.js
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const paths = require('./config/paths');
const config = {
entry: {
index: path.join(__dirname, paths.custServReactIndex),
},
output: {
path: path.join(__dirname, paths.outputScriptsFolder),
filename: '[name].js',
publicPath: paths.outputScriptsFolder,
},
mode: 'development',
module: {
rules: [
{
// Compile main index
test: /\.jsx?$/,
loader: 'babel-loader',
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
}),
],
};
module.exports = config;
.babelrc
{
"ignore": ["node_modules"],
"presets": ["env", "stage-0", "react"]
}
That being said, any idea on why some relative imports are failing and how can I solve so?
You need to add resolve extensions. Add the below config in Webpack and restart React app
resolve: {
modules: [
path.resolve("./src"),
path.resolve("./node_modules")
],
extensions: [".js", ".jsx"]
}
I use vue.js and vue-cli to create a project.
vue init webpack my-project
I am trying to create a component using http://photo-sphere-viewer.js.org/, thus I installed it using
npm install --save photo-sphere-viewer
Then it was downloaded in node_modules and appears in the package.json under dependencies as
"photo-sphere-viewer": "^3.2.3",
And I tried to import in a component, VR-Pano.vue, inside the script tag using
import PhotoSphereViewer from 'photo-sphere-viewer';
And
var PhotoSphereViewer = require('photo-sphere-viewer');
But when I run npm run dev
This dependency was not found:
photo-sphere-viewer in ./~/babel-loader/lib!./~/vue-loader/lib/selector.js?type=script&index=0!./src/components/VR-Pano.vue
I tried:
npm cache clean && npm update -g
Did some researches on webpack, but didn't really know what's going on as I am not too familiar with webpack. I was expecting it to be a simple process, but I suspect something isn't setup properly for my webpack or I did something very stupid.
Here is my webpack.base.conf.js
var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
entry: {
app: './src/main.js'
},
// target: 'electron-main',
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'#': resolve('src')
}
},
module: {
rules: [
{
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter')
}
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('[path][name].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
}
I took this debugging opportunity to learn more about npm and webpack.
It looks like the creators of photo-sphere-viewer did not specify where their "main" file was, the file that gets returned when you import or require. I think by default npm looks for index.js at the project root. But a lot of times, package creators put their distribution files under a dist or lib directory. The photo-sphere people did this, but did not specify the location in their package.json. The solution is to add
"main":"./dist/photo-sphere-viewer.min.js"
to the photo-sphere-viewer package.json file. Make sure to add a trailing comma if you're not putting it at the very end. Also i would recommend filing an issue on their Github, this seems like a bug..
Alternatively, you can also do
import PhotoSphereViewer from 'photo-sphere-viewer/dist/photo-sphere-viewer.min.js';