Why webpack is including node_modules of dependency? - javascript

I have two modules inside the same directory, managed both by lerna js. One of them is a library that others module includes. Both of them packed by webpack following webpack library authoring.
But, when I launch webpack in the app dir, the process includes all library/node_modules dependencies inside the app, for example vue.js. In library vue is "devDependency" while in the app is "dependencies". This implies two Vue context in navigator. Somebody known why?
Thanks.

You need to add an alias:
module.exports = {
...
....
},
resolve: {
modules: ["node_modules",
alias: {
'vue$': 'vue/dist/vue',
'jquery': 'jquery/dist/jquery.min.js'
}
},
...

Thanks to #evocateur
"Node resolves symlinks when requiring, which means libraries (like React and Vue) that are singletons will break. You need to add resolve.alias webpack config so it always chooses the "root" node_modules packages."
Putting in webpack following works perfectly in resolve.alias:
vue: path.resolve(__dirname, './node_modules/vue/')

Related

Running a webpack bundled JS library with "umd" module system in Nodejs throws error: "self" is not defined

Recently I have been developing a JavaScript library and now I want to publish it on npm.
Then I learned that I've to use a package bundler. So I started learning webpack and followed their guide Authoring a library form the docs.
In their guide they suggested using umd module type to support all module systems so I used "umd". But when I tried to run (via importing) the generated bundle file in Node.js, it throws an exception saying "self is not defined"! Then I opened the bundled file and found that there is a variable named self but I don't know what is its purpose.
Whatever long story short, then I tried commonjs and commonjs2 module type and published a test package and tried it in both react and node environment and it worked perfectly. Sadly then it didn't work in browser environment with the <script> tag. Now my question is what module type should I use?
Here is my webpack.config.js
const path = require("path");
module.exports = {
mode: "production",
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "index.js",
library: {
type: "commonjs", // umd, commonjs2, ....
},
},
};
Here is my project structure
|- /dist
|- /src
|- package.json
|- webpack.config.json
Webpack versions:
"webpack": "^5.53.0"
"webpack-cli": "^4.8.0"
Thanks in advance. I highly appreciate your time on StackOverflow <3.
After lots of time wasting I found the answer in a github issue of webpack.
I can use library.type: "umd" but I just have to add the following in my webpack configuration.
module.exports = {
output: {
globalObject: 'this' // This line was missing
}
}

Vue JS note transpiling node module

I have a Vue app created with vue create app and have the following settings in the babel.config file:
module.exports = {
presets: [
'#vue/cli-plugin-babel/preset'
]
}
My Vue config file also looks like this:
module.exports = {
configureWebpack: {
optimization: {
splitChunks: false
}
},
css: {
extract: false,
}
}
At the moment when I run vue-cli-service build it compiles all my modules and styles into 1 bundled JS file.
There is an issue however with one of my NPM modules: socket.io-client
It appears that the way that Vue is compiling my app, it is not transpiling something within this package which is causing syntax errors in Internet Explorer 11.
I am fairly sure the problematic code in socket.io-client lies with one of it's dependencies called debug.
What I would like to do is have this package (socket.io-client) also transpiled so that I don't get the error in IE11.
I would have thought that Vue CLI would do this out of the box when you run the build but perhaps something has been setup wrong in my babel or Vue configuration? How could I resolve this issue?
Thanks!
You can use transpileDependencies option in your vue.config.js.
By default babel-loader ignores all files inside node_modules. If you want to explicitly transpile a dependency with Babel, you can list it in this option.
Example:
module.exports = {
...
transpileDependencies: [
'socket.io-client'
]
}
Found the issue here:
https://github.com/socketio/socket.io-client/issues/1328
Reverting the problematic package to previous version fixed it

Why does my Webpack bundle include jQuery twice?

I set up a parent module with 2 submodule dependencies. The parent module has no specified jQuery dependency, but each submodule specifies jQuery ^3.3.1 as a dependency (results in 3.4.1 for each submodule). I Webpacked the parent module and then I see in the generated bundle file that jQuery 3.4.1 is included twice. What should I be doing so that the same version of jQuery isn't included twice? I did try the splitchunks plugin and it did generate chunks but jQuery was still in there twice. I thought that Webpack is supposed to automatically analyze dependencies in the module graph and optimize the bundled code? I haven't yet tested NPM peer dependencies or the Webpack de-dupe plugin. I'm also wondering if there's something about jQuery itself to where Webpack can't/decides not to de-dupe automatically?
In both submodules' index.js files, I'm using:
import $ from "jquery"
In each submodule's package.json I specified:
"dependencies": {
"jquery" : "^3.3.1"
}
Then I did a npm install on each submodule.
module.exports = {
resolve: {
alias: {
// fix every jQuery to our direct jQuery dependency. Shariff 1.24.1 brings its own jQuery and it would be included twice without this alias.
'jquery': __dirname + '/node_modules/jquery/',
},
},
};
Note -happens because Shariff 1.24.1 defines jQuery as its own dependency instead of defining it as peer dependency in the package.json.
Refrence
I found that module resolution can automatically happen downwards (into child folders) of an entry point folder, but not upwards (in module folders outside of the entry point folder). I found that I needed to "tell" Webpack about these other module locations by adding a "resolve" object to Webpack.config:
resolve: {
modules: [
path.resolve(__dirname, "src/modules/pagetype/node_modules"),
path.resolve(__dirname, "src/modules/sitewide/node_modules"),
path.resolve(__dirname, "src/modules/template/node_modules"),
"node_modules"
]
}, // resolve

How can I import React Components as a package/module from some other(non-project) directory?

I have a couple of React Components in a folder, which is not a react project. The Directory Structure i am following for components is:
~/components/Component1/index.jsx
~/components/Component2/index.jsx
Now I have a React project (built with create-react-app), named "myapp" I want to import those React Components as a package or module in my project.
I have tried mentioning a dependency in my package.json, but gives an error, because I can't mention absolute paths in package.json.
I don't want to publish these components as a npm package.
Kindly help me with this
The problem was:
I was trying to wrap material-ui components like iconButton, iconMenu, etc. to make the components easy to use programatically. To put them into a git repository I need a example directory with a seperate react project using the components I developed. So, I need to develop a package that hold components' definitions and exporting them to be used in other project. I want to keep my implementations private so I cannot even publish it to npm.js.
[you can see the question statement for thorough understanding of thr ptoblem.]
Coming to the solution help me doing the needed, I created a new project with yarn adding minimal dependencies. i.e.
babel
babel-cli
babel-core
babel-loader
babel-preset-es2015
babel-preset-react
babel-preset-stage-2
html-webpack-plugin
raw-loader
webpack
webpack-dev-server
and then devDependencies
react
react-dom
material-ui [occasional]
After the installations, [HERE COMES THE PART] I created a webpack.config.js with following script:
const path = require('path')
const webpack = require('webpack')
module.exports = {
devtool: 'cheap-eval-source-map',
entry: './docs/entry.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
resolve: {
alias: {
genericcomponents: path.join(__dirname, 'src')
}
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
}
]
},
devServer: {
contentBase: 'docs/'
}
}
In the code above, after mentioning the output the entry, devtool and output of the transpilation process. I actually have another thing to define, which is alias, I defined the alias with the directory holding the components.
Now this package will hold all the components with the name I provided in the alias parameter.
After that I mentioned loaders for transpilation and file format to jsx, so It will accept the source with JSX Syntax.
And at last I mentioned my the directory where I placed my index.html and entry.js file.
Following is the directory structure of my project:
I have my App.jsx Component in docs folder. which can now import any of the components in the components folder by the giving the package name.
You are welcome to discuss of any of the problem occurred in the above solution.
I know the answer might sound very basic but is there any reason why don't you just copy paste the components into the new app and just use them as any other component ?

Using bower modules with Webpack 2

I am new to Webpack and I started with Webpack2. I can't manage to use require or import of modules from bower_components folder. Is it possible to do so and if it is can you provide me an example or something.
This is my webpack.config file:
You can configure resolve.modules to also look in bower_components.
resolve: {
modules: ['bower_components', 'node_modules']
}
This will first look into bower_components and if it can't find the module it will look into node_modules. If you don't inlcude node_modules you won't be able to use packages installed from npm.

Categories

Resources