Understanding r.js, almond, and relative paths - requirejs

I see this answer but AFAICT it's not working for me. Maybe I'm doing something stupid.
I'm using almond and grunt-contrib-requirejs. I've tried a bunch of stuff
Here's my layout
.
├── Gruntfile.js
├── 3rdparty
│ ├── require.js
├── src
│ ├── lib.js
│ └── main.js
└── node_modules
   └── almond
      └── almond.js
And here's my grunt-contrib-requirejs config
requirejs: {
full: {
options: {
baseUrl: "./",
name: "node_modules/almond/almond.js",
include: [ "src/main.js" ],
out: "dist/app.js",
optimize: "none",
},
},
},
main.js looks like this
requirejs(['./lib',], function(lib) {
lib.hello();
});
lib.js looks like this
define([], function() {
return {
hello: function() {
console.log("hello from lib");
},
};
});
If run a page that uses require.js as in
<script src="3rdparty/require.js" data-main="src/main.js"></script>
It runs great. You can see it live it here. Check the console and you'll see it prints hello from lib
So I run grunt. Then I run a page that uses dist/app.js and I get the error
Uncaught Error: undefined missing lib
Here's a live page.
Checking the generated dist/app.js I see lib has been turned into this
define('src/lib',[], function() {
...
});
And main is including it like this
requirejs(['./lib'], function(lib) {
...
});
In other words, the id that r.js generated src/lib doesn't match the id that main is referencing ./lib.
This seems like a very straight forward example for r.js. Like practically "hello world".
What am I doing wrong?
One thing I've tried is changing the baseUrl to ./src
requirejs: {
full: {
options: {
baseUrl: "./src",
name: "node_modules/almond/almond.js",
include: [ "src/main.js" ],
out: "dist/app.js",
optimize: "none",
},
},
},
But now I get
{ [Error: Error: ENOENT: no such file or directory, open '/Users/gregg/temp/grunt-contrib-requirejs-example/src/node_modules/almond/almond.js'
at Error (native)
]
originalError:
{ [Error: ENOENT: no such file or directory, open '/Users/gregg/temp/grunt-contrib-requirejs-example/src/node_modules/almond/almond.js']
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '/Users/gregg/temp/grunt-contrib-requirejs-example/src/node_modules/almond/almond.js',
fileName: '/Users/gregg/temp/grunt-contrib-requirejs-example/src/node_modules/almond/almond.js' } }
So I try fixing the almond path
requirejs: {
full: {
options: {
baseUrl: "./src",
name: "../node_modules/almond/almond.js",
include: "main",
out: "dist/app.js",
optimize: "none",
},
},
},
But that fails as well
{ [Error: Error: ERROR: module path does not exist: ../node_modules/almond/almond.js for module named: ../node_modules/almond/almond.js. Path is relative to: /Users/gregg/temp/grunt-contrib-requirejs-example
at /Users/gregg/temp/grunt-contrib-requirejs-example/node_modules/requirejs/bin/r.js:30214:35
]
originalError: [Error: ERROR: module path does not exist: ../node_modules/almond/almond.js for module named: ../node_modules/almond/almond.js. Path is relative to: /Users/gregg/temp/grunt-contrib-requirejs-example] }
What am I not getting?
The entire thing is checked into github here if you'd like to work with it.

So here's the answer.
r.js prefers module names not paths
requirejs: {
full: {
options: {
baseUrl: "./src",
paths: {
almond: "../node_modules/almond/almond",
}
name: "almond",
include: [ "main.js" ],
out: "dist/app.js",
optimize: "none",
},
},
},

Related

How do I change the input dir in ViteJS?

I'm trying to build/compile a demo page for my plugin with ViteJS. How do I pinpoint ViteJS to my file that needs to be compiled?
my-plugin/
├─ demo/
│ ├─ resources/js/
│ │ ├─ app.js <---- This needs to be read (`npm run build:demo`)
│ ├─ public/js/
│ │ ├─ app.js <---- This should be my ViteJS demo output (outDir)
├─ node_modules/
├─ dist/ <---- This works ✅ (`npm run build:dist`)
│ ├─ index.mjs
│ ├─ index.umd.js
├─ src/
│ ├─ index.js
├─ index.html <---- This is the demo index.html that is needed for GitHub (cannot change the location)
├─ package.json
I have added these lines of code in
// package.json
...
"scripts": {
"build:dist": "LIB_NAME=dist vite build",
"build:demo": "LIB_NAME=demo vite build",
"build": "npm run build:dist && npm run build:demo",
},
...
I want to run npm run build:demo. But I get errors, like:
[vite]: Rollup failed to resolve import "/demo/public/js/app.js" from "index.html".
This is most likely unintended because it can break your application at runtime...
My vite.config.js looks like this:
import { defineConfig } from 'vite';
import vue from '#vitejs/plugin-vue';
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
const path = require('path');
const config = {
dist: {
build: {
lib: {
entry: path.resolve(__dirname, './src/index.js'),
name: 'VueResponsiveVideoBackgroundPlayer',
fileName: 'vue-responsive-video-background-player',
},
rollupOptions: {
external: ['vue'],
output: {
// Provide global variables to use in the UMD build
// Add external deps here
globals: {
vue: 'Vue',
},
exports: 'named',
},
},
outDir: './dist',
},
plugins: [
vue(),
cssInjectedByJsPlugin(),
],
},
demo: {
// <--------- This is the part where I have to change something
// root: './demo/resources/js/',
build: {
outDir: './demo/public/js',
},
plugins: [
vue(),
cssInjectedByJsPlugin(),
],
},
};
const currentConfig = config[process.env.LIB_NAME];
if (currentConfig === undefined) {
throw new Error('LIB_NAME is not defined or is not valid');
}
// https://vitejs.dev/config/
export default defineConfig({
...currentConfig,
plugins: [
vue(),
cssInjectedByJsPlugin(),
],
});
It would be awesome, if I could somehow say to ViteJS please use ./demo/resources/js/app.js as the input and after the compile set the output to ./demo/public/js.app.js.
Here is the source if you need it.
Yeah I found the solution:
It took me a while, but have look at my vite.config.js file.
// https://www.raulmelo.dev/blog/build-javascript-library-with-multiple-entry-points-using-vite-3
import { defineConfig } from 'vite';
import vue from '#vitejs/plugin-vue';
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
const path = require('path');
const config = {
// npm run build:dist for npm
dist: {
build: {
outDir: './dist',
lib: {
entry: path.resolve(__dirname, './src/index.js'),
name: 'VueResponsiveVideoBackgroundPlayer',
fileName: 'vue-responsive-video-background-player',
},
rollupOptions: {
external: ['vue'],
output: {
// Provide global variables to use in the UMD build
// Add external deps here
globals: {
vue: 'Vue',
},
// in index.js we use a named + default export.
// We hide the error message with 'named'
exports: 'named',
},
},
},
},
// npm run build:demo for the demo page
demo: {
build: {
outDir: './demo/public/build',
rollupOptions: {
input: './demo/resources/js/app.js',
output: {
chunkFileNames: 'js/[name].js',
entryFileNames: 'js/[name].js',
},
},
},
},
};
const currentConfig = config[process.env.LIB_NAME];
if (currentConfig === undefined) {
throw new Error('LIB_NAME is not defined or is not valid');
}
// https://vitejs.dev/config/
export default defineConfig({
...currentConfig,
plugins: [
vue(),
cssInjectedByJsPlugin(),
],
});

Renaming the optimized files in requirejs folder level optimization

I'm using requirejs with Grunt in my project. I could able to successfully perform the folder level optimization through grunt-requirejs tool as below.
requirejs : {
std: {
options: {
mainConfigFile: 'src/js/main.js',
appDir: "src",
baseUrl: "js",
dir: "dist",
modules: [
{
name: "main"
}
],
removeCombined: true,
wrap: true,
almond: true,
replaceRequireScript: [{
files: ['dist/index.html'],
module: 'main'
}]
}
}
}
All the js files are concatenated and minified in main.js and css files in style.css. How can I rename these files main.js and style.css into something like app.min.js and app.min.css. Can I able to accomplish this using r.js or I've to use some external plugin?

Browserify Module not found

I am trying to use the 'typestring' npm module with browserify but get the following error in the Chrome console:
Uncaught Error: Cannot find module 'typescript-api'
I see that 'typescript-api' is a dependency of typestring and it does appear in the node_modules folder of 'typestring'...
Am i missing something? My grunt-browserify task is:
browserify: {
dist: {
files: {
'./public/bundle.js': './public/main.js'
},
options: {
commondir: true,
bundleOptions: {
debug: true
},
transform: ['deamdify']
}
}
},

merging files with dependencies - require js

I'm using require JS.
I want to marge two files into one.
I'm using for that require js plugin for grunt.
First file is raty jquery script.
Second is my own file like this:
define('userGlosowanie', ['jquery', 'raty'], function ($) {
'use strict';
return {
init: function () {
}
}
});
And here is my grunt script:
requirejs: {
userGlosowanie: {
options: {
baseUrl: "js/libs",
paths: {
userGlosowanie: "../dev/uzytkownik-glosowanie",
raty: "raty/jquery.raty",
},
name: "userGlosowanie",
out: "js/build/uzytkownik.min.js",
preserveLicenseComments: false,
}
},
},
Problem is that I've got error:
Running "requirejs:user" (requirejs) task
>> Error: ENOENT, no such file or directory
>> 'D:\strony\www\polskieszlaki\js\libs\jquery.js'
>> In module tree:
>> user
Warning: RequireJS failed. Use --force to continue.
my jquery file is in separate file and I don't want to include it in compiled file. How to do it?
If you don't want to include jquery in build file just mark it as empty: in path config.
options: {
paths: {
userGlosowanie: "../dev/uzytkownik-glosowanie",
raty: "raty/jquery.raty",
jquery: "empty:"
}
}
You can exclude a particular module/file from getting included in the combined/optimized file using the exclude option
In your case it will look like -
requirejs: {
userGlosowanie: {
options: {
baseUrl: "js/libs",
paths: {
userGlosowanie: "../dev/uzytkownik-glosowanie",
raty: "raty/jquery.raty",
},
out: "js/build/uzytkownik.min.js",
name: "userGlosowanie",
exclude: "jquery"
preserveLicenseComments: false,
}
}
}
With modules and dir(output dir) option, you may not be able to set the output file name, but the optmized file with same name as the module will be placed in the directory set by option dir
requirejs: {
userGlosowanie: {
options: {
baseUrl: "js/libs",
paths: {
userGlosowanie: "../dev/uzytkownik-glosowanie",
raty: "raty/jquery.raty",
},
dir: "../public",
modules : [{
name: "userGlosowanie",
exclude: "jquery"
}],
preserveLicenseComments: false,
}
}
}
Sample usage/explanation is here

Requirejs Gruntfile cannot locate almond

i'm trying to use almond.js in grunt to combine my files into on .js and uglify it.
My configuration in grunt is like this:
requirejs: {
compile: {
options: {
baseURL: "www/js/lib",
mainConfigFile: 'www/js/main.js',
name: '../../../node_modules/almond/almond',
include: '../main',
out:'../target/app.min.js',
findNestedDependencies: true,
optimize: 'uglify',
}
}
},
my main.js is this:
require.config({
baseUrl: "js/lib",
paths: {
app: '../app',
tpl: '../tpl'
},
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
},
'backbone-indexeddb': {
deps: ['backbone', 'IndexedDBShim']
},
'IndexedDBShim': {
deps: ['backbone']
}
}
});
If i try to run grunt requirejs i get an error:
Error: Error: ERROR: module path does not exist: project/www/js/js/lib/../../../node_modules/almond/almond.js for module named: ../../../node_modules/almond/almond. Path is relative to: project
at /project/node_modules/grunt-contrib-requirejs/node_modules/requirejs/bin/r.js:25964:35
which i do not understand, where does the second /js/ in the path come from? It does not exist in my file structure, i have my project folder set up like this
project
gruntfile
node_modules
almond
almond.js
www
index.html
js
app
lib
main.js
Oh, i'm configuring the baseurl twice, shouldn't do that. If i remove the baseurl parameter in the gruntfile it works fine.

Resources