webpack vendor module root reference-able as "vendor" - javascript

I have the following setup:
app/src
app/vendors/
app/vendors/foo
app/vendors/foo/src
I set an env variable like APP_VENDOR=foo and would like webpack 1.x to have ./src and "./" + process.env.APP_VENDOR" + /src as the resolver roots in a way that I can reference files from the vendor directory in my JS files as vendor/file and it would import app/vendors/foo/src/file.js
Is that possible with webpack 1.x?

You can use resolve/alias.
In your webpack config file do something like that:
...
resolve: {
root: path.resolve(__dirname),
alias: {
vendor1: "src/vendor",
vendor2: path.join(__dirname, process.env.APP_VENDOR + "/src")
}
}
...
Then in the modules just import using alias definition:
import MyVendor from "vendor1/MyVendor.js"; //it will lookup into ./src/vendor/MyVendor.js

Related

importing css/sass files in webpack using aliases

Is there any way to import .scss / .css files using aliases
// webpack.config.js
resolve: {
alias: {
styles: path.resolve(__dirname, "src/styles/"),
}
}
and in main.js
// main.js
import "styles/main.scss";
Webpack alias' should be prefoxed with tilde in sass imports. So your syntax should be:
import "~styles/main.scss";

Webpack is erroring when I attempt to import a directory containing modules

I'm trying to create a small npm library to make interfacing with an API a little neater. My folder structure is as follows...
dist/
index.js
src/
index.js
endpoints/
endpoint1.js
package.json
webpack.config.js
Within my src/index.js file I have..
import {endpoint1} from './endpoints'
module.exports = class lib {
...
}
When I npm run build (which runs webpack --display-error-details --mode production) webpack throws a big error saying "Module not found: Error: Can't resolve './endpoints' in 'my\project\dir\src'.
My webpack.config.js file currently looks like...
const path = require('path');
module.exports = {
mode: 'production',
entry: path.join(__dirname, '/src/index.js'),
output: {
path: path.resolve('dist'),
filename: 'index.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /.js?$/,
exclude: /(node_modules)/,
use: 'babel-loader'
}
]
},
resolve: {
modules: [
path.resolve(__dirname, 'src/endpoints')
],
extensions: ['.js']
}
};
I can see similar questions have been asked before and the resolutions listed don't seem to work for me so I thought I'd post it incase im making a rookie error. If any more info is required just say! Sorry if it's fairly wall of texty. Thanks.
The correct import would be:
import endpoint1 from 'endpoint1';
By using resolve.modules you tell Webpack to look up non relative paths in that folder. The module name is "enpoint1".
But actually you should only do this with libraries that you use across your project, for an endpoint a relative import will be appropriate:
import endpoint1 from "./endpoints/endpoint1";
import {endpoint1} from './endpoints' means this:
import from file ./endpoints/index.js something that is exported under the name enpoint1 in that file. If you import directory then it refers to index.js under that directory, not to all other files. It doesn't exist in your setup.
Names inside {} refer to named imports. This goes only for es6 modules-style imports like import {...} from. If you ommit {} then you import the default. CommonJs-style imports like const {...} = require('') work differently. CommonJs does not have named imports and exports. It just will import default from that file and then fetch a field via object destructuring.
What you export is something unnamed(i.e. default) from file ./endpoints/enpoint1.js
Something is unnamed because you use module.exports = which is CommonJS-style export. CommonJS does not support named exports. This is equevalent to export default class lib ... in es6 modules-style exports.
IF you want to import many files under directory you can consider these solutions:
1) Often single import points are created. You make a index.js file. In it you import manually every file under the directoy that you want to export. Then you export it under names. Like this:
import a from './a.js';
import b from './b.js';
import c from './c.js';
export { a, b, c };
Then it will work
2) In some rare cases in might make sence to use fs.readdir or fs.readdirSync to scan the entire directory and dynamicly require files in a loop. Use it only if you must. E.g. db migrations.

Webpack alias in Laravel Mix to node_modules

I would like to use an alias in VUE.JS in a Laravel 5.8 project to import css and js I have in my module.
webpack.mix.js
mix.webpackConfig({
resolve: {
alias: {
'alias': path.resolve(
__dirname,
'~myModule/src'
)
}
}
});
In my VUE App.js I would like import the css folder and I wrote:
resources/js/app.js
// css files
import 'alias/lib/css'
// js files
import 'alias/lib/script'
But I'm wrong something becouse the alias is not resolved:
ERROR in ./resources/js/app.js
Module not found: Error: Can't resolve 'alias/lib/css' in...
Can you help me to fix the issue?
After so many attempts I got the issue. The code was good but I was missing to load the webpack.mix.js properly:
From Laravel Mix documentation:
The webpack.mix.js file is your entry point for all asset compilation. Think of it as a light configuration wrapper around Webpack. Mix tasks can be chained together to define exactly how your assets should be compiled.
But if you are using npm run watch it is not (re)loaded before to compile new changed assets. This means:
if you are in watch mode (npm run watch) exit and restart it to load new updated webpack.config.js if you changed it.
Finally it worked! And it resolve new alias properly!
Here the final config I used in webpack.config.js:
mix.webpackConfig({
resolve: {
alias: {
'aliasName': path.resolve(
__dirname,
'node_modules/MyModule/src/'
)
}
}
});
Another alternative is:
mix.webpackConfig({
resolve: {
modules: [
'node_modules'
],
alias: {
'aliasName' : 'MyModule/src/'
}
}
});
Then in my Vue component (or in vue app.js, just in case)
<template>
<myModule-component></myModule-component>
</template>
require('aliasName/lib/css'); // to load full css directory
require('aliasName/lib/script'); // to load full js directory
import MyModuleComponent from 'aliasName/widgets/MyModuleComponent.vue'
...
export default {
...
components: {
'myModule-component': MyModuleComponent
}

Set context dir for import when include some file in entry.js?

In entry.js file I have :
import 'index.js';
And that index.js has many imports from another dir like :
import test from 'modulename'.
But I have moved all modules to another dir and want to keep just index.js in main dir. So that's why I must rewrite all imports with new dir location like this :
import test from ../anotherdir/modulename
How to get rid of this and force webpack to search modules in new dir?
Now I am using webpack allias and this help me if path is too long but it still require to change all imports.
You can use resolve alias in webpack
Resolve
These options change how modules are resolved. webpack provides
reasonable defaults, but it is possible to change the resolving in
detail. Have a look at Module Resolution for more explanation of how
the resolver works.
webpack.config.js
module.exports = {
//...
resolve: {
alias: {
Utilities: path.resolve(__dirname, 'src/utilities/'),
Templates: path.resolve(__dirname, 'src/templates/')
}
}
};
Now, instead of using relative paths when importing like so:
import Utility from '../../utilities/utility';
you can use the alias:
import Utility from 'Utilities/utility';

Typescript can't find modules which are imported with webpack alias

I am currently setting up my project to be a bit cleaner, especially in the frontend part with references.
In hindsight I noticed that I was very generous with the folder structure for my frontend files and ended up with lots of layers. That's why I decided to look into what webpack can do for this case, and found out about the alias functionality.
This is how I set it up:
resolve: {
alias: {
components: path.resolve(__dirname, "Scripts/Views/Components"),
data: path.resolve(__dirname, "Scripts/Data"),
definitions: path.resolve(__dirname, "Scripts/Definitions"),
helper: path.resolve(__dirname, "Scripts/Helper"),
scripts: path.resolve(__dirname, "Scripts"),
views: path.resolve(__dirname, "Scripts/Views"),
},
extensions: [".tsx", ".ts", ".js", ".jsx"],
modules: ["node_modules"]
}
As you can see, I created alias' for various folders here.
This is my folder structure:
Now, let's hop into e.g. the LoginDialog.tsx. Here I am trying to import like this:
import { IErrorAttachedProperty } from "definitions/formHelper";
However, all I end up with here is an error that no module could be found this way.
What am I doing wrong here?
If it is of any significance - The webpack.config.js resides in the same directory as the Scripts folder.
you have to config tsconfig.json for typescript
"baseUrl": "./",
"paths": {
"components/*": [
"./src(or any other path)/Scripts/Views/Components"
]
},
here is nice example ts alias
Ok, so to avoid confusion for others I'm posting my solution/findings:
Yes, you can just use tsconfig.json without needing resolve/alias in Webpack. You should just do it once with Typescript setup.
EDIT: Nope, turns out you do need resolve/alias section in webpack.config.js. Typescript will be happy without it, but then you will get Webpack errors when it builds. Do both to make it work.
TIP: Make sure the paths you provide in the paths section of tsconfig.json are relative to the baseUrl entry point. Don't make them relative to the tsconfig.json file, baseUrl is like the project root for the non-relative module imports defined with paths.
From Typescript docs, absolute modules names (import * from package-a) are relative to baseUrl ~ https://www.typescriptlang.org/docs/handbook/module-resolution.html#base-url
All module imports with non-relative names are assumed to be relative to the baseUrl.
Relative modules (import * from ./packages) are just from current file as stated:
Note that relative module imports are not impacted by setting the baseUrl, as they are always resolved relative to their importing files.
So if you have:
./packages
./package-a
./package-b
./index.ts
./tsconfig.json
Your tsconfig.json would look like:
{
"compilerOptions": {
"baseUrl": "./packages",
"paths": {
"package-a/*": [ "./package-a/*" ],
},
},
"include": [
"./packages/**/*"
]
}
Then your webpack.config.json would look like:
{
resolve: {
alias: {
'package-a': path.resolve(__dirname, 'packages/package-a/'),
}
},
}
Then you can import from index.ts like this:
import { pkgAThing } from 'package-a';
// or
import { otherPkgAThing } from 'package-a/dir/dir`;
Which is alternative to relative style:
import { pkgAThing } from './packages/package-a`;

Categories

Resources