I'm having trouble understanding how to set the base URL for requirejs given the structure of my project.
The issue: Not all html files will be on the same folder level. The script file paths keep changing depending on the location of the html page.
What I've tried: I've scoured the API, but I just don't understand what the BaseURL should be to get the correct path for all pages. I've tested variations (../js/lib, /js/lib/, I tried not including it all in the main.js file) but this one below is the only one that seems to produce the correct result on certain files.
Main.js
requirejs.config({
baseUrl: '../js/lib',
paths: {
'jquery' : (document.addEventListener) ? ['vendor/jquery'] : ['vendor/jquery-1.9.1']
},
shim: {
'foundation/foundation': {
deps: ['jquery']
},
'foundation/foundation.alert': {
deps: ['jquery', 'foundation/foundation']
},
'vendor/slick.min': {
deps: [
'jquery',
'foundation',
'foundation/foundation.interchange'
],
exports: 'slick'
}
}
});
requirejs(['jquery'
, 'foundation/foundation'
]);
Folder Structure
Main Folder
│
│ Some Folder
│ ├── css
│ ├── js
│ │ ├── lib
│ │ │ ├── foundation
│ │ │ │ ├── foundation.alert.js
│ │ │ │ ├── ...(foundation component js files)
│ │ │ │ ├── foundation.js
│ │ │ ├── vendor
│ │ │ │ ├── jquery-1.9.1.js
│ │ │ │ ├── jquery.js
│ │ │ ├── foundation.min.js
│ │ │ ├── slick.min.js
│ │ │ └── slickModule.js
│ │ ├── main.js
│ │ └── require.js
│ ├── html
│ │ ├── components
│ │ │ ├── slider.html [All scripts throw 404: Main Folder/Some Folder/html/js/lib/vendor/file.js ]
│ │ ├── home.html [loads files as expected]
│ │ ├── second.html [loads files as expected]
│ │ ├── subfolder
│ │ │ └── random.html
│ ├── extra folder
│ │ └── index.html [All scripts throw 404: Main Folder/Some Folder/extra folder/js/lib/vendor/file.js ]
│ │
│ Another Folder
│ ├── index.html [All scripts throw 404]
/html/components/slider.html
When I try to call require this way, the slickModule's url is
"Main Folder/Some Folder/html/js/lib/slickModule.js" - note 'html' is added after the base url
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script data-main="../../js/main" src="../../js/require.js"></script>
<script>
require(['../js/main'], function () {
require(['slickModule']);
});
</script>
</head>
<body>
...
</body>
</html>
Could someone help me to see why this could be happening?
If it's even possible, what can I do to get the base URL to be consistent?
Summary
Don't require the same file twice in a row, especially if it's the file that changes your configuration options, especially if it uses relative paths.
Use a single application entry-point. If you can't start your application in a single place, it will be difficult (though not impossible) to use the data-main attribute.
Use the paths configuration option to point to files, not relative paths when you're including the module or setting up the config.
Single Entry Point
First of all, you're likely running into some issues with your data-main attribute since its behavior when used for multiple entry points is undocumented. As it says:
If you want to to do require() calls in the HTML page, then it is best to not use data-main. data-main is only intended for use when the page just has one main entry point, the data-main script. For pages that want to do inline require() calls, it is best to nest those inside a require() call for the configuration
Multiple requires
Secondly, you're using the data-main attribute to load your config which defines the behavior of the library (in other words, the require/requirejs function is customized), but then you use that customized tool to load the configuration again:
<script data-main="../../js/main" src="../../js/require.js"></script>
<script>
require(['../js/main'], function () {
require(['slickModule']);
});
</script>
I'm almost positive this introduces some strange behavior.
Use paths to avoid ../
Third, your baseUrl is automatically set to either the location of the HTML that loaded it, or the location of the data-main script. You can use this to your advantage by creating a single entry point (probably js/main), and then defining the paths configuration option to hide nested modules.
In other words, your application should never need to request ../ (or any variation thereof) because anything nested should be hidden by a paths entry like:
"paths": {
"slickModule": "lib/slickModule"
}
I know this answer doesn't specifically solve your problem, but I'm positive that one of these issues - when corrected - will solve your 404 problem.
I had this same issue in an ASP.NET MVC4 application, structured like so:
Main Folder
├── Scripts
│ ├── Libraries
│ │ ├── jquery
│ │ | ├── jquery-1.10.2.min.js
...
What I did was use my server side technology's method to determine the app's "root location". In my case, this is HttpRequest.ApplicationPath, which "gets the ASP.NET application's virtual application root path on the server." (source).
My requirejs setup looks like:
<script type="text/javascript">
var require = {
baseUrl: '#(Request.ApplicationPath)/Scripts',
paths: {
jquery: 'Libraries/jquery/jquery-1.10.2.min',
...
}
}
</script>
<script type="text/javascript" src="#Url.Content("~/Scripts/Libraries/require/require.js")"></script>
To summarize:
My base URL is the root application path plus the Scripts folder
Each path starts with the folder that is a child of Scripts
This forces requirejs to use an absolute path to the libraries instead of trying to figure out the relative ones from various directories.
Any scripts not specified in the paths configuration should also start with the folder that is a child of Scripts
You shouldn't need to use ../ anywhere in your configuration
Hope that helps, obviously you'll need to adjust this for whatever technology you're using.
Since you have html-files in different folders at different levels, setting your baseUrl as a relative path (i.e. ../lib/js) will work for some files, but for all, that's to be expected. You need to set an absolute path, from your root directory to your lib folder, e.g. if 'Main Folder' is your root, your baseUrl should be /Some Folder/js/lib/ or /Some Folder/js/lib. I hope that helps.
Related
I'm trying to deploy on a live server a small flask app that also uses javascript and some Three.js library files. When trying to import the required three.js files in my app.js file I get the 404 resource not found error. I'm using a digitalocean droplet and the folder structure is as follows:
app
├── __init__.py
├── static
│ ├── css
│ │ └── style.css
│ ├── js
│ │ └── app.js
| | └── three(folder with all the three library files)
│ └── models
│ └── poly_ann.glb
├── templates
│ └── index.html
└── views.py
the app.js is of type "module" in index.html. the top of the app.js looks like this:
import * as THREE from '/js/three/build/three.module.js';
import { GLTFLoader } from '/js/three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from '/js/three/examples/jsm/loaders/DRACOLoader.js';
import { GUI } from '/js/three/examples/jsm/libs/dat.gui.module.js';
.
.
.
needless to say that as a pure html/javascript app on my local server these paths works just fine.
As you can see the app.js file is sitting inside the static folder as all the tutorials suggest.
The problem is pathfinding of three.js libraries. the three folder is sitting inside the js folder but it's not finding it for some reason.
Any help will be appreciated.
It would be usefull to post the exact error but sometimes it help if you add a . before the slash, for example import { GUI } from '/js/three/examples/jsm/libs/dat.gui.module.js';
becomes import { GUI } from './js/three/examples/jsm/libs/dat.gui.module.js';
I recently started my first project with Next.js and since then my pages directory has grown a lot. Now I want to separate my pages and group them into modules, ending up with something like 'src/modules/*/pages/*'.
Researching the topic I came accross exportPathMap, a function that I can include in my next.config.js file and then map custom paths to my pages, but it seems like I'd need to add a new path for every page I create, which is not ideal. I want to give to Next a single expression, something like 'src/modules/*/pages/*', and let it resolve the pages and routes for me (like you would do in a ormconfig.json file to map entities when using TypeORM).
I suppose I could group my page components directly inside pages, like pages/a-module/*, but I also have components, hooks and other logic that I'd like to segregate into modules. I could also try using Node's fs to iterate through my project file structure and map the the page folders, but I'd like to avoid that if possible.
You could use symlinks. You would need one for each module, but not one for each nested path within the module. Your directory structure would look like:
├── modules
│ ├── bar
│ │ └── pages
│ │ ├── first.js
│ │ └── second.js
│ └── foo
│ └── pages
│ ├── first.js
│ └── second.js
├── pages
│ ├── _app.js
│ ├── bar -> ../modules/bar/pages
│ ├── foo -> ../modules/foo/pages
│ ├── index.js
Which would end up with routes:
/bar/first
/bar/second
/foo/first
/foo/second
I'm not sure what that buys you, though, really. Now your modules folder will have the same clutter that pages used to. You don't have to have all of the component content in the files in pages. It could be as simple as:
// pages/foo/first.js
import FirstContent from '../../modules/FirstContent'
export default function First() {
return <FirstContent />
}
As #Roman Mkrtchian mentioned, you're not supposed to do so. My suggestion is that, if you want to organize your files into modules like me, creating a file structure similar to this one:
src
├── modules
│ ├── foo
│ | └── pages
| | ├── one
| | | ├── index.jsx
| | | └── styles.js <- For `styled-components`; could be a css file
| | └── two
| | ├── index.jsx
| | └── styles.js
| └── bar
| └── pages
| └── three
| ├── index.jsx
| └── styles.js
├── shared
└── ...
You should take another approach. As #erich2k8 said, you don't need all of the component content to be in the files inside /pages, you could create the same structure above, but add /pages directly to src:
src
├── modules
├── shared
└── pages
├── foo
| ├── one.jsx
| └── two.jsx
└── bar
└── three.jsx
And inside src/pages/foo/one.jsx, for instance, you'd import src/modules/foo/pages/one, like so:
import OneContent from '../../modules/foo/pages/one';
const One = () => <OneContent />;
export default One;
Yes, you'd still need to create a new file for each page you create inside /modules, but it spares you from a really bad time messing with Next behavior.
This is not permitted by the Next.js team on purpose for reasons explained in this post and in the posts referenced there.
You may read some of the discussions before deciding if you really want to hack the files structure to do it anyway.
I'm using Parceljs to bundle html and js. It works really well with less configuration.
Now, I'm facing i18n issue.
Google recommends using different URLs for each language version of a page.
https://support.google.com/webmasters/answer/182192
So, I want to generate language specific static html from one template like below.
.
├── dist
│ ├── ja
│ │ └── index.html
│ ├── app.c328ef1a.js
│ └── index.html
├── i18n
│ ├── default.json
│ └── ja.json
└── source
├── app.js
└── index.html
source/index.html
<html>
<body>
<h1>__TITLE__</h1>
<script src="/app.js"></script>
</body>
</html>
i18n/default.json
{
"__TITLE__": "Hello world!"
}
i18n/ja.json
{
"__TITLE__": "こんにちは 世界!"
}
Is there a way to deal with this issue using parceljs?
Or, should I write a code for prebuild?
Thank you.
Self answer:
I found a great answer here.
It mentions node-static-i18n package that generates i18n static HTML.
This tool isn't a plugin of parceljs, but it seems to be able to generate expected results.
Welcome yet another answer.
In visual studio cod, How to navigate from feature to step definition. Do we need any additional plugins or any configuration needs to be added. I have downloaded the Cucumber (Gherkin) Full Support plugin but still cannot navigate from .feature to the step definition.
The documentation of Cucumber (Gherkin) Full Support plugin has the explanation for it.
You need to add the below in your settings:
{
"cucumberautocomplete.steps": [
"test/features/step_definitions/*.js",
"node_modules/qa-lib/src/step_definitions/*.js"
],
"cucumberautocomplete.syncfeatures": "test/features/*feature",
"cucumberautocomplete.strictGherkinCompletion": true
}
cucumberautocomplete.steps => provide the path of the step definitions.
cucumberautocomplete.syncfeatures => provide the path of the feature files
After this(might be after a restart), cmd + click(on mac) would take to the step definition.
Thanks,
Naveen
Having installed the extension alexkrechik.cucumberautocomplete, I tried modifying the settings from both the UI of the extension and its corresponding settings JSON (by default, mine were in ~/.config/Code/User/settings.json). But this didn't work because I got this error in the *.feature files: Was unable to find step for "Some feature description".
I noticed I had skipped a step mentioned in the extension docs... By default, it was getting the settings.json from my userspace and not my work(project)space.
For me, the solution was to go to the root directory of my project (usually outside of /src, where you have the package.json and node_modules/) and create a .vscode/ folder. Then, create a settings.json file and paste there the cucumberautocomplete configuration with the paths relative to this brand new file.
Below I show a schema:
myProject/
├── node_modules
├── package.json
├── subdir1
│ ├── src
│ └── test
│ └── e2e
│ └── src
│ ├── features
│ │ └── myfeature1.feature
│ ├── mypageobject1.po.ts
│ └── steps
│ └── mystep1.step.ts
└── .vscode
└── settings.json
An example of configuration would be:
{
"editor.detectIndentation": false,
"window.zoomLevel": 0,
"cucumberautocomplete.steps": [
"subidr1/test/e2e/src/steps/*.steps.ts"
],
"cucumberautocomplete.syncfeatures": "subidr1/test/e2e/src/feature/*.feature"
}
Note that you could use **/*.steps.ts and **/*.feature paths but every time the extension settings file changes, when you Ctr + Click on a feature description, you will need to wait for the editor to resolve the paths. Otherwise, there is no waiting time.
Recently I've been involved in a Project, a PHP panel. It uses pure PHP and they have given me permission to access a folder to add my functionalities as an add-on to the existing panel.
The file structure is like so:
/
├── assets/
│ └── ...
├── config/
│ └── ...
├── test/
│ └── ...
.
.
.
├── MYAPP/
│ └── api/
│ │ ├── foo/
│ ├── index.html
│ └── ...
.
.
.
├── myApp.php
├── ...
myApp.php file has some requires to PHP files to load the theme and some scripts at the top and at the bottom.
I can require the index.html from MYAPP folder to load the main page of the app itself with all of the scripts and stylesheets working correctly as it is located in the root.
The URL now is “webpage.com/myApp.php”
Is it possible to create an SPA using the current file myApp.php with Vue and Vue-router like so?
“webpage.com/myApp.php/#/addCategory”
“webpage.com/myApp.php/#/editCategory”
…
Or should I make URL calls like this and load the content old fashion way?
“webpage.com/myApp.php? page=addCategory”
“webpage.com/myApp.php? page=editCategory”
-...
I have tried the vue spa template changing the base option with the vue-router but it didn't work.
What could be my options? Any ideas?