Using webpack and babel with files from parent project directory - javascript

I have a project set up like this and I'm trying to require file-a.js from file-b.js.
project-name/
node_modules/
src/
file-a.js
tools/
tool-name/
node_modules/
src/
file-b.js
webpack.config.js
package.json
package.json
My webpack 1.13.0 configuration was working until I added babel-loader 6.2.4 with babel-preset-es2015 6.6.0. Then I started getting error messages.
ERROR in /home/dan/dev/dan/project-name/src/file-a.js
Module build failed: Error: Couldn't find preset "es2015" relative to directory "/home/dan/dev/dan/project-name/src"
Now I have a hunch that this is happening because it's looking for babel-preset-es2015 in the upper package.json. I can make this error go away by installing it at that level, but then I get a similar message about the babel module not being there.
I've tried all sorts of things, symlinked the upper src directory into the inner project, used resolve.root and resolve.alias to try and manually resolve the folder without the nested path. Used context to set the project root as the outer folder, but it still picked up the wrong node_modules.
How can I force webpack to use the correct node_modules folder?

By default webpack looks in ./node_modules, ../node_modules, and ../../node_modules.
To force it to only use a specific directory, you can set an absolute path for the module modulesDirectories property in the resolve section:
module.exports = {
// ...
resolve: {
modulesDirectories: [path.join(__dirname, 'node_modules')]
}
}
More details on moduleDirectories in webpack's documentation

Related

Can I make TypeScript include node_modules for transpilation?

OK so I have an interesting situation in setting up my Node.js TypeScript project. I want to be able to refer to my local modules using a non-relative require reference. The way TypeScript and Node.js look up modules is to look for a node_modules directory in the current directory and then each parent directory until they find such a directory containing the reference. So let's say I have a module I want to reference in the following directory structure:
/node_modules <-- Main NPM modules dir
/...
/package.json
/src
/node_modules <-- My local modules dir
/modules
/myModule.ts
/scripts
/init.ts
... and in init.ts I reference myModule like this:
import myModule from "modules/myModule";
As I understand it, I want TypeScript to transpile my node_modules directory over to the output dist directory along with all my other .ts file directories, so that the dist directory looks like this:
/node_modules <-- Main NPM modules dir
/...
/package.json
/dist
/node_modules <-- My local modules dir
/modules
/myModule.js
/scripts
/init.js
Then, when Node.js looks for the module it will find it at dist/node_modules/modules/myModule.js. So in this case I actually do want TypeScript to include the node_modules directory in its input files. I seem to be missing something fundamental, though, because TypeScript actually ignores this directory by default.
Is my scenario a legitimate one for including the node_modules directory, and if so, how can I make TypeScript include it in the transpilation when I just run tsc (and therefore it will use my tsconfig.json file)?
UPDATE:
I have found that I can make it include my node_modules directory by explicitly putting it in the include directive in the .tsconfig.json like so:
"include": [
"./src/node_modules/**/*",
"./src/**/*"
]
The question remains; am I getting something fundamentally wrong here, because I am having to override something TypeScript excludes by default? I've tested this and when I make it transpile node_modules, it does indeed find my local modules correctly.
That's not correct to include node_modules for transpilation. Because node_modules contains javascript and doesn't requires second transpilation in case of ts libraries, they should have declarations in .d.ts.
If you have custom types, or you want to add types to some libraries that don't have them, you need to use own declarations or #types/* packages.
in your tsconfig.json you can define type roots (where to load declarations from).
{
"compilerOptions": {
"typeRoots": ["./declarations", "./node_modules/#types"],
"types": ["node"],
}
}
then you can install npm i --save-dev #types/node#^12 for example to get declarations of nodejs v12.
and define your own declarations in declarations for express for example: ./declarations/express/index.d.ts
import * as express from 'express';
declare module 'express' {
export interface Request {
user?: {
id: string;
name: string;
}
}
}

Grunt: have package.json and Gruntfile.js on different folders

Im having problems trying to implement grunt on diferent folders, in my root i have:
<root>/package.json
<root>/node_modules
And inside another folder, my gruntfile with diferent subfolders and files wich i work:
<root>/apps/static/Gruntfile.js
If i go to root and execute
grunt --gruntfile /apps/static/Gruntfile.js MyTaskName
I get:
Local Npm module "grunt-contrib-concat" not found. Is it installed?
Local Npm module "grunt-contrib-cssmin" not found. Is it installed?
Local Npm module "grunt-contrib-clean" not found. Is it installed?
Local Npm module "grunt-contrib-watch" not found. Is it installed?
Local Npm module "grunt-contrib-uglify" not found. Is it installed?
And i run several times npm install.
On my gruntfile.js y have
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');
I triple check and folders are ok (in fact, originally gruntfile and package where in the same folder and everything was working perfect, run several task and everything is ok). I really need to have a common package.json and node_modules on root and the Gruntfile.js on a specific project folder
Any idea whats going on? thanks in advance
Grunt makes certain assumptions regarding the location of gruntfile.js.
When you specify the location of gruntfile.js using the --gruntfile option, Grunt sets the current directory to the directory containing the specified file:
// Change working directory so that all paths are relative to the
// Gruntfile's location (or the --base option, if specified).
process.chdir(grunt.option('base') || path.dirname(gruntfile));
And when Grunt loads NPM tasks, it does so relative to the current directory:
var root = path.resolve('node_modules');
var pkgfile = path.join(root, name, 'package.json');
There is a --base option with which the current directory can be specifed, but whether or not that will solve your problem (without introducing other problems) I do not know. The simplest solution is likely to locate gruntfile.js where it wants and expects to be located.
Sometimes, it may be the need of project to have Gruntfile.js in a different folder than package.json.
I had a very similar use-case where there were multiple submodules each with its own build process, one of them was Grunt. But at the same time I wanted to have a common package.json just to avoid multiple node_modules folders being created, so that common dependencies (including transitive) use to install once. It helped in reducing install time as well as disk usage.
I was expecting a solution in Grunt itself. But as #cartant mentioned, Grunt has made certain assumptions.
So, here is what I did:
In Gruntfile.js,
Define a function:
function loadExternalNpmTasks(grunt, name) {
const tasksdir = path.join(root, 'node_modules', name, 'tasks');
if (grunt.file.exists(tasksdir)) {
grunt.loadTasks(tasksdir);
} else {
grunt.log.error('Npm module "' + name + '" not found. Is it installed?');
}
}
And instead of
grunt.loadNpmTasks('grunt-contrib-concat');
do:
loadExternalNpmTasks(grunt, 'grunt-contrib-concat');
Reference: https://github.com/gruntjs/grunt/blob/master/lib/grunt/task.js#L396

Error: Files glob patterns specified did not match any files

This is my github
When I npm run dev
This error will happen,but it doesn't influence my project
Although everything is ok,I want to solve this error
fuhaodeMacBook-Pro:learnRedux fuhao$ npm run dev
learnRedux#1.0.0 dev /Users/fuhao/Workspace/fuhao/learnRedux
node server.js
Listening at http://localhost:8010
webpack building...
Error: Files glob patterns specified did not match any files
webpack built 955aef52aa91434f6ef1 in 2670ms
In my case I got same error:
It was caused because there were no scss or css files in the /src folder and my webpack config contains such settings for stylelint loader:
new StyleLintPlugin({
configFile: './stylelint.json',
context: "./src",
files: "**/*.scss"
})
I didn't find any solution for that error as it didn't affect my build at all.

Bower points to wrong path (jQuery-form-validator)

I just installed the jQuery-form-validator in my project using bower install jquery-form-validator --save and then I ran grunt wiredep.
The package was correctly added to bower_components and to the bower.json file, but in the generated HTML, it points to the wrong directory.
Grunt wiredep added the following line:
<script src="bower_components/jquery-form-validator/jquery.form-validator.min.js"></script>
while it should be:
<script src="bower_components/jquery-form-validator/form-validator/jquery.form-validator.min.js"></script>
What is the best way to fix this? Should I just manually place the files in the right directory or can I configure something in Bower to make it point to the right path?
The issue is with the main property of jquery-form-validator bower.json - it is pointing at the wrong path:
"main": "jquery.form-validator.min.js",
This is later used by wiredep to locate the main .js file and hence the wrong src path.
You can solve this by overriding the main property of jquery-form-validator as described here. Add the following to your bower.json file:
"overrides": {
"jquery-form-validator": {
"main": "form-validator/jquery.form-validator.min.js"
}
}
It can also be a good idea to notify the jquery-form-validator about the main property.

r.js can't build because of ENOENT error...says it can't find ".bin/bower"

I'm trying to get r.js to optimize all my Require-related files but am getting an error.
My site is in a directory called "myCrazysite" and is structured like this :
(not all the files)
myCrazysite
js/
buildform.js
search.js
app.build.js
vendor/
jquery
r.js
app.build.js looks like this:
({
appDir: "../",
aseUrl: "js",
optimize: "none",
dir: "buildOut",
modules: [
{
name: ["buildform", "search"]
}
]
})
I'm going into js/ and runningnode ../r.js -o app.build.js. I've also globally installed the CLI tool with npm and run r.js -o app.build.js from same directory.
When I do either of these two things, I get the following error:
ENOENT, no such file or directory '/Users/me/Sites/myCrazysite/node_modules/.bin/bower'
at Object.fs.statSync (fs.js:684:18)
The steps I've taken are:
navigated to to the above mentioned ".bin" directory on the CLI..the
bower directory is there.
upgraded to node v0.10.18
uninstalled & reinstalled bower
uninstalled the CLI tool and run node ../r.js -o
app.build.js
globally reinstalled the CLI tool back, deleted r.js
from the site root, navigated to js/ and run r.js -o app.build.js
I'm using require v.2.1.8.
Never mind...I figured it out.
The issue was that the .bin/bower file was causing some conflict and just needed to be deleted. It was a stray shortcut file from (I think) a bower-related grunt plugin. As I wasn't using the plugin, I just used npm to uninstall it, then hard-deleted the file .bin/bower.
Moral of the story: the command line always tells you what to do...usually.

Categories