webpack 2 with bower - javascript

I'm currently working on project, which depends partialy on 'bower only' dependencies and I need somehow to add bower_components module to Webpack 2 bundle. How can I do it? Documentation from previous version doesn't work and bower-webpack-plugin is outdated. I'm using Webpack#2.2.1.
I added this code to webpack.config.js:
resolve: {
extensions: ['.js', '.jsx'],
modules: ['bower_components', 'node_modules']
}
But unfortunately this doesn't work.

Use current version of documentation
Correct resolving of path to bower_components with path module had helped me. Maybe it will helps you.

Webpack2 can be used with bower with resolving options, you can read more here: https://gist.github.com/sokra/27b24881210b56bbaff7#resolving-options
A simple example of webpack.config.js resolving a bower.json file:
module.exports = {
entry: './file.js',
output: {
filename: 'my-first-webpack.bundle.js'
},
resolve: {
modules: [ "bower_components"],
descriptionFiles: ["bower.json"]
}
};

Related

Error: Unable to resolve module ... could not be found within the project or in these directories: node_modules

Error: Unable to resolve module navigation/stack-routes from /Users/jacksaunders/gymzoo/src/navigation/tabs/MainTabs.tsx: navigation/stack-routes could not be found within the project or in these directories:
node_modules
Hello there! I have just tried to set up absolute imports (using navigation/stack instead of ../../../navigation/stack)
I am not sure what is happening because it looks to be okay in my IDE but my metro is flagging the following error.
Here is my tsconfig for context:
I have tried deleting my node modules, npm i and pod install but theres no luck.
Please throw your suggestions at me! Or advise me on how to solve this.
All the best,
Jack :)
You need to update your babel.config.js to understand the root imports you're using here, because your .tsconfig only takes care about the code before it's transcompiled.
You can use the babel-plugin-root-import to achieve this.
npm package: https://www.npmjs.com/package/babel-plugin-root-import
Example babel.config.js could look like this:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'babel-plugin-root-import',
{
paths: [
{
rootPathSuffix: './src',
rootPathPrefix: 'src',
},
{
rootPathSuffix: './src/navigation',
rootPathPrefix: 'navigation',
},
]
},
],
],
};
It's not an only option though, you can also use babel-plugin-module-resolver, which is more popular (https://www.npmjs.com/package/babel-plugin-module-resolver).

Why am I getting Webpack 'module not found' error?

I am refactoring project which has a working webpack bundling. Basically, I am trying to change the root source folder of the project and I am having an issue. I have been debugging for so long but I cannot see what I am missing.
In my tsconfig.json file I have the following settings
"baseUrl": "./",
"paths": {
"src/*": [
"src/*"
],
"test/*": [
"test/*"
]
}
In the webpack.common.js file I have the following
const includePaths = ['node_modules', 'src'];
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx'],
modules: includePaths,
},
My source folder is in the root of my project. Basically I should be able to reach with ./src
This is how I bundle:
rm -rf ./build && webpack --config webpack.dev.js
webpack.dev.js
merge(common, config, {
entry: {
main: [
`${__dirname}/src/environment`,
'webpack-hot-middleware/client?path=__webpack_hmr&dynamicPublicPath=true',
`${__dirname}/src/main`,
],
},
When I run the bundler in watch mode I see something like:
These dependencies were not found:
src/<somefolder>/<somefile> in ./src/<somefolder>/<somefile.tsx>
Module not found: Error: Can't resolve ...
The weird thing is, when src folder was under another folder eg. frontend/src, it was bundling without an issue. I suspect something is off in the tsconfig but I cannot figure it out. Can someone please help?
Adding alias like this worked but I don't really understand how old version was working without the alias.
alias: {
src: path.resolve(__dirname, 'src'),
},

How to pass externals from webpack to jest?

I've got this webpack config as part of my grunt building process:
module.exports = {
options: {
output: {
path: path.resolve('../ui/static/js'),
filename: '[name].js',
chunkFilename: '[id].[name].js',
libraryTarget: 'amd',
library: '[name]'
},
externals: [
'jquery',
'lodash',
'backbone',
'backbone.layoutmanager',
'moment',
'spin',
'lib/select2.min',
'dispatcher'
],
resolve: {
root: path.resolve('../ui'),
alias: {
'jst': 'static/jst'
}
}
We are moving to react now, and I need to import some files in my test files, where this dependencies included, but jest can not find them:
Cannot find module 'lib/select2.min' from 'helpers.js'
Cannot find module 'jst/templates_jst' from 'base-view.js
What is the right way to resolve this issue?
Here's what works today with webpack#4.11.1 and jest#23.1.0. Assuming this is your externals webpack config:
externals: {
react: {
root: 'React',
commonjs2: 'react',
commonjs: 'react',
amd: 'react',
},
}
You'll need to map each external library to be properly resolved in your jest config like so:
moduleNameMapper: {
"^./react": path.resolve(__dirname, 'node_modules/react'),
}
While debugging your issue, be sure to check what your built component file looks like. You want to be sure that you see something like:
!function(e,t){if("object"==typeof exports&&"object"==typeof module)
module.exports=t(require("react"));
else if("function"==typeof define&&define.amd)define(["react"],t);
else{var n="object"==typeof exports?t(require("react")):t(e.React);
Important bit being react for commonjs and amd, and React for the browser.
You need to mock the external lib.
Example with jquery:
Create a __mocks__ folder in the same level of __test__ folder.
Inside that, create a file with the same name of the dependency, in this case, jquery (jquery.js).
Inside the test file, use jest.mock function to reference the mock external dependency: jest.mock('jquery');
from jest the docs:
https://facebook.github.io/jest/docs/manual-mocks.html
Hope it helps.
For my case using the __mocks__ would be a bit verbose but I used the
jest.mock('myModule', () => {/* module impl */}, {virtual: true})
In case the __mocks__ suggestion is to verbose for you too check out the docs here

Better way to import in ES6 [duplicate]

I'm still confused how to resolve module paths with webpack. Now I write:
myfile = require('../../mydir/myfile.js')
but I'd like to write
myfile = require('mydir/myfile.js')
I was thinking that resolve.alias may help since I see a similar example using { xyz: "/some/dir" } as alias then I can require("xyz/file.js").
But if I set my alias to { mydir: '/absolute/path/mydir' }, require('mydir/myfile.js') won't work.
I feel dumb because I've read the doc many times and I feel I'm missing something.
What is the right way to avoid writing all the relative requires with ../../ etc?
Webpack >2.0
See wtk's answer.
Webpack 1.0
A more straightforward way to do this would be to use resolve.root.
http://webpack.github.io/docs/configuration.html#resolve-root
resolve.root
The directory (absolute path) that contains your modules. May also be an array of directories. This setting should be used to add individual directories to the search path.
In your case:
webpack config
var path = require('path');
// ...
resolve: {
root: path.resolve('./mydir'),
extensions: ['', '.js']
}
consuming module
require('myfile')
or
require('myfile.js')
see also: http://webpack.github.io/docs/configuration.html#resolve-modulesdirectories
For future reference, webpack 2 removed everything but modules as a way to resolve paths. This means root will not work.
https://gist.github.com/sokra/27b24881210b56bbaff7#resolving-options
The example configuration starts with:
{
modules: [path.resolve(__dirname, "app"), "node_modules"]
// (was split into `root`, `modulesDirectories` and `fallback` in the old options)
resolve.alias should work exactly the way you described, so I'm providing this as an answer to help mitigate any confusion that may result from the suggestion in the original question that it does not work.
a resolve configuration like the one below will give you the desired results:
// used to resolve absolute path to project's root directory (where web pack.config.js should be located)
var path = require( 'path' );
...
{
...
resolve: {
// add alias for application code directory
alias:{
mydir: path.resolve( __dirname, 'path', 'to', 'mydir' )
},
extensions: [ '', '.js' ]
}
}
require( 'mydir/myfile.js' ) will work as expected. If it does not, there must be some other issue.
If you have multiple modules that you want to add to the search path, resolve.root makes sense, but if you just want to be able to reference components within your application code without relative paths, alias seems to be the most straight-forward and explicit.
An important advantage of alias is that it gives you the opportunity to namespace your requires which can add clarity to your code; just like it is easy to see from other requires what module is being referenced, alias allows you to write descriptive requires that make it obvious you're requiring internal modules, e.g. require( 'my-project/component' ). resolve.root just plops you into the desired directory without giving you the opportunity to namespace it further.
In case anyone else runs into this problem, I was able to get it working like this:
var path = require('path');
// ...
resolve: {
root: [path.resolve(__dirname, 'src'), path.resolve(__dirname, 'node_modules')],
extensions: ['', '.js']
};
where my directory structure is:
.
├── dist
├── node_modules
├── package.json
├── README.md
├── src
│   ├── components
│   ├── index.html
│   ├── main.js
│   └── styles
├── webpack.config.js
Then from anywhere in the src directory I can call:
import MyComponent from 'components/MyComponent';
I have resolve it with Webpack 2 like this:
module.exports = {
resolve: {
modules: ["mydir", "node_modules"]
}
}
You can add more directories to array...
My biggest headache was working without a namespaced path. Something like this:
./src/app.js
./src/ui/menu.js
./node_modules/lodash/
Before I used to set my environment to do this:
require('app.js')
require('ui/menu')
require('lodash')
I found far more convenient avoiding an implicit src path, which hides important context information.
My aim is to require like this:
require('src/app.js')
require('src/ui/menu')
require('test/helpers/auth')
require('lodash')
As you see, all my app code lives within a mandatory path namespace. This makes quite clear which require call takes a library, app code or a test file.
For this I make sure that my resolve paths are just node_modules and the current app folder, unless you namespace your app inside your source folder like src/my_app
This is my default with webpack
resolve: {
extensions: ['', '.jsx', '.js', '.json'],
root: path.resolve(__dirname),
modulesDirectories: ['node_modules']
}
It would be even better if you set the environment var NODE_PATH to your current project file. This is a more universal solution and it will help if you want to use other tools without webpack: testing, linting...
If you're using create-react-app, you can simply add a .env file containing
NODE_PATH=src/
Source: https://medium.com/#ktruong008/absolute-imports-with-create-react-app-4338fbca7e3d
Got this solved using Webpack 2 :
resolve: {
extensions: ['', '.js'],
modules: [__dirname , 'node_modules']
}
This thread is old but since no one posted about require.context I'm going to mention it:
You can use require.context to set the folder to look through like this:
var req = require.context('../../mydir/', true)
// true here is for use subdirectories, you can also specify regex as third param
return req('./myfile.js')
Simply use babel-plugin-module-resolver:
$ npm i babel-plugin-module-resolver --save-dev
Then create a .babelrc file under root if you don't have one already:
{
"plugins": [
[
"module-resolver",
{
"root": ["./"]
}
]
]
}
And everything under root will be treated as absolute import:
import { Layout } from 'components'
For VSCode/Eslint support, see here.
I didn't get why anybody suggested to include myDir's parent directory into modulesDirectories in webpack, that should make the trick easily:
resolve: {
modulesDirectories: [
'parentDir',
'node_modules',
],
extensions: ['', '.js', '.jsx']
},

Webpack doesn't resolve properly my alias

I am trying to have a namespace for my app to work as a module, and import my components using this namespace and limit the use of relative path.
Although, even though I followed the webpack documentation for alias here: http://webpack.github.io/docs/configuration.html#resolve-alias
I can't make it to work.
This is how my resolve object looks like:
resolve: {
root: path.resolve(__dirname),
alias: {
myApp: './src',
},
extensions: ['', '.js', '.json', '.jsx']
}
path.resolve(__dirname) resolves /Users/Alex/Workspace/MyAppName/ui/
I import my file that way in the file /Users/Alex/Workspace/MyAppName/ui/src/components/Header/index.jsx:
import { myMethod } from 'myApp/utils/myUtils';
I get the following error during the build:
ERROR in ./src/components/Header/index.jsx
Module not found: Error: Cannot resolve module 'myApp/utils/myUtils' in /Users/Alex/Workspace/MyAppName/ui/src/components/Header
# ./src/components/Header/index.jsx 33:19-56
I also tried with modulesDirectories but it doesn't work either.
Do you have any idea what is wrong?
Resolving the alias to the absolute path should do the trick:
resolve: {
alias: {
myApp: path.resolve(__dirname, 'src'),
},
extensions: ['', '.js', '.jsx']
}
Check this webpack resolve alias gist with a simple example.
Another solution to limit the number of relative paths is to add your ./src folder as root instead of aliasing it:
resolve: {
root: [path.resolve('./src')],
extensions: ['', '.js', '.jsx']
}
Then you will be able to require all folders inside ./src as if they where modules. For example, assuming you have the following directory structure:
.
├── node_modules
├── src
│   ├── components
│   └── utils
you would be able to import from components and utils like this:
import Header from 'components/Header';
import { myMethod } from 'utils/myUtils';
Something like having an alias for each folder inside ./src.
This might be obvious to many but if you, like me, have spent too much time trying to figure out why it suddenly does not work when moving from Windows or Mac to Linux then check casing in the paths...
Me and everyone else on the project are using Windows or Mac but at home I dual boot ubuntu which I enjoy using. On cloning our code and running webpack i got a whole lot of Cannot resolve module... errors. I spent more time than I'd like to admit searching for some obscure error in node, npm, webpack or anything until I noticed the paths of the failing modules were something like #app/Shared/settings.js and the require was require('#app/shared/settings'). Windows doesn't care so everything was fine all until I started working on linux. As it turned out problem was not with webpack, node or anything else so that's probably why I didn't find anyone suggesting that this could be the problem.
Hope this saves some time for someone. Or maybe I'm just dumb, I don't know.
Most of the time it depends on your project folder structure. If your webpack file is inside a folder then make sure you handle it accordingly
.
├── node_modules
├── src
│ ├── components
│ └── config/webpack.config.js
modules.exports = {
resolve: {
extensions: ['.js', '.jsx'],
alias: {
Components: path.resolve(__dirname, '../src/components/'),
}
},
...
resolve: {
...
}
}
Also it often happens that we name our folder as "source" but use "src" in path.
Darn! that copy paste has taken alot of my debug time
Hope this helps someone who is facing such issues due to the above reasons.
I got the same error. Finnaly I found the problem was that I wrote resolve twice. And the second resolve override the previous one.
My code is like this:
modules.exports = {
resolve: {
extensions: ['.js', '.jsx'],
alias: {
Components: path.resolve(__dirname, 'src/components/'),
}
},
...
resolve: {
...
}
}
More help can be found in Webpack Doc
I use without next syntax :
resolve: {
alias: {
Data: __dirname + '/src/data'
},
extensions: ['.js', '.jsx', '.json']
}
import points from 'Data/points.json';
In my case, I wanted to alias mobx, so that any import of mobx would always return the same instance, regardless of whether the import call was from my main app, or from within one of the libraries it used.
At first I had this:
webpackConfig.resolve.alias = {
mobx: path.resolve(root, "node_modules", "mobx"),
};
However, this only forced imports of mobx from my app's own code to use the alias.
To have it work for the library's import calls as well, I had to do:
webpackConfig.resolve.alias = {
mobx: path.resolve(root, "node_modules", "mobx"),
"LIBRARY_X/node_modules/mobx": path.resolve(root, "node_modules", "mobx"),
};
It's odd, because I'm pretty sure just having the mobx alias used to work for both contexts before, but now it apparently doesn't (Webpack v4.41.2).
Anyway, the above is how I solved it. (In my case, I needed it to prevent two mobx instances from being used as that breaks things, and LIBRARY_X was symlinked using npm-link, so I couldn't delete/unify the secondary mobx folder itself)

Categories

Resources