I'm trying to watch my app's js files and dependencies's css & js files for link them in my index.html file.
I'm using grunt-contrib-watch for the job, but it seems that it doesn't work as I expected. There are directories in the file system tree that doesn't trigger the watch task.
this is my grunt watch config:
watch: {
vendors: {
files: ['www/vendors/**/*.js', 'www/vendors/**/*.css'],
tasks: ['wiredep']
},
app: {
files: ['www/app/**/*.js', 'www/app/**/*.css', 'www/css/**/*.css'],
tasks: ['tags']
}
}
this is my folders structure:
C:.
└───www
├───app
│ └───modules
│ └───main
│ └───controllers
├───css
├───images
└───vendors
├───angular
├───bootstrap
│ ├───dist
│ │ ├───css
│ │ ├───fonts
│ │ └───js
│ ├───fonts
│ ├───grunt
│ ├───js
│ └───less
└───jquery
├───dist
└───src
├─── ...
Here is the PROBLEM. When I add/delete a js or css file to a directory that already have js/css file, the watcher task triggers and it works. But any other folder that doesn't have js/css placed in (and the folder is placed in vendors or app folders), doesn't trigger the watcher, and the task won't run.
Why is that? and how can I solve it? I want the watcher to work on any level in the directory's tree.
I'm using grunt 0.4.5, and grunt-contrib-watch version 0.6.1.
Related
I have a Vite 4 project that uses vanilla JS & no frameworks. When I reference an asset using CSS url(), it throws a 404 error. The path works fine in HTML img src. I saw the answer for Vue but don't know how it applies to my project without a framework. Merely importing an asset from the index.js file changes nothing.
_search-input.scss
.search-input {
width: 100%;
background-image: url("../../assets/icons/search.svg");
}
Index.js:
import "./styles/index.scss"
console.log("index file")
Project structure:
├── src/
│ ├── assets/
│ │ └── icons/
│ │ └── search.svg
│ ├── styles/
│ │ ├── components/
│ │ │ └── _search-input.scss
│ │ └── index.scss
│ └── index.js
└── index.html
I removed a single ../ from the path and now the image loads. However, isn't ../assets/icons/search.svg an invalid path? From search-input.scss I'm supposed to go up two levels to get to src/ and then reach assets. My IDE also complains that this path can't be resolved. Why does this work? What is this path relative to?
CSS url() paths are relative to the current css location, in contrast to HTML img src which is not relative to the current path.
Maybe try to add another ../ to your css path.
I installed react-vis via npm install react-vis
and its possible to write
import { XYPlot, LineSeries } from 'react-vis';
I want to know how the systems knows where XYPlot and LineSeries are? I looked in the node_modules directory and there is no index.js.
The structure of the react-vis directory is the following
my-app/
├─ node_modules/
│ ├─ react-vis/
│ │ ├─ dist/
│ │ ├─ es/
│ │ ├─ CHANGELOG.md
│ │ ├─ LICENSE
│ │ ├─ package.json
│ │ ├─ README.md
How does this work?
I researched and for example this does not helped me: Where { component } from 'react' is located when we are importing ReactJS?
Edit
I think it looks in the package.json that is inside the react-vis directory. There are two entries that look interesting. "name": "dist" and "module": "es". I think that i have to look inside the dist directory. Inside the dist directory, there is an index.js file. I open this file and on line 318 it says exports.XYPlot = _xyPlot2.default;
In the es folder inside the index.js there is on line 98 this: export { _XYPlot as XYPlot }; I don't know if this is important.
Im using the lib sucrase to use ES6 modules in NodeJS(import/export) and i'm using the follow command to generate a build of my project in commonJ:
sucrase ./src -d ./build --transforms imports where ./src is my project folder and ./build is the output. When the process is finished i have a build folder with my javascripts files converted to commonJS but the assets files and every no-JS files are moved to this build folder, like images and css files in public directory or PUG files in views, only the JS files and directories are moved. I dont know if is possible do this with sucrase cause i've already read the doc, but maybe its possible do with another lib(sucrase with other lib).
My project structure(src)
│ app.js
│
├───public
│ │
│ ├───images
│ │ some-image.png
│ │
│ ├───javascripts
│ │ script.js
│ │
│ └───stylesheets
│ styles.min.css
│
├───routes
│ index.js
│
└───views
│ index.pug
│ layout.pug
│
└───parts
footer.pug
header.pug
My project structure after converted(build)
│ app.js
│
├───public
│ │
│ ├───images
│ │
│ ├───javascripts
│ │ script.js
│ │
│ └───stylesheets
│
├───routes
│ index.js
│
└───views
└───parts
I read sucrase document and found that ONLY support load JS files (JSX, TS, etc). If you want to load another kind of files, use file-loader.
Sucrase also offers a package called #sucrase/webpack-loader. You can give it a try, but I'm not sure it supports to load images, non-JS files and so on.
Last but not least, sucrase documentation is not great, and I highly recommend not using it because you will have trouble with it community like this. Use Webpack, Babel or parcel instead if you want to deep dive into bundler. For modern approach for example with ReactJS, I higly recommend using gatsby to forget all things about bundler, you totally can move your react app into gatsby easily.
Maybe this might not help you resolve problem, but I hope I can give you a picture on your problem. Sharing is more important thing. Good luck!
Premise
Let's say I have two different AMD-based AngularJS apps, each of them with their own sets of controllers, directives, services, etc. Each of them are bundled in their own dist/{app-name}.min.js and loaded in <script> tags in the same HTML page (this is all in the context of a CMS that then contains these apps among other things)
Now the apps end up sharing some of the services, directives, and vendor libraries like angular itself, moment, jQuery, etc, so I've made another folder for all of these resources, which results in a bundle that will be added to the page before the js bundles of the apps:
<script src="/some-path/dist/shared-resources.min.js"></script>
<script src="/some-path/dist/first-app.min.js"></script>
<script src="/some-path/dist/second-app.min.js"></script>
This is the resulting folder structure:
.
├── shared-resources/
│ ├── dist/
│ ├── src/
│ │ └── common/
│ │ ├── directives/
│ │ ├── modules/
│ │ ├── services/
│ │ └── vendor/
│ └── build.js
│
├── first-app
│ ├── dist/
│ ├── src/
│ │ ├── first-app/
│ │ │ ├── controllers/
│ │ │ ├── modules/
│ │ │ ├── services/
│ │ │ ├── directives/
│ │ │ └── app.js
│ │ └── first-app.js
│ └── build.js
│
└── second-app
├── dist/
├── src/
│ ├── second-app/
│ │ ├── controllers/
│ │ ├── modules/
│ │ ├── services/
│ │ ├── vendor/
│ │ └── app.js
│ └── second-app.js
└── build.js
This is an example of what the build.js file for the common modules looks like
({
baseUrl: 'src',
removeCombined: true,
out: 'dist/shared-resources.min.js',
paths: { // forcing a `common/{modulename}` convention
'common/jquery': 'common/vendor/jquery.min',
'common/moment': 'common/vendor/moment.min',
'common/angular': 'common/vendor/angular/angular.min',
},
shim: {
'common/angular': {
exports: 'angular',
}
},
include: [
'common/modules/vendors', // Just a bundle of every vendor modules
'common/directives/common-directive',
'common/services/common-service'
],
})
Now my intention was to have all the shared modules being namespaced with common/, so each of the apps could require common/angular, common/directives/common-directive, and so on, and then exclude the common path when creating their bundle (since all the common modules are already present in the shared-resources.js bundle), for example:
// first-app/src/first-app/controllers/app-controller.js
define([
'first-app/modules/controllers',
'first-app/services/app-service',
'common/services/common-service'
], function (controllers) {
'use strict';
controllers.controller('AppController', ['CommonService', 'AppService', function (CommonService, AppService) {
CommonService.call();
AppService.call();
}]);
});
// first-app/build.js
({
baseUrl: 'src',
out: 'dist/first-app.min.js',
paths: {
'common': 'empty:'
},
name: 'first-app',
deps: ['first-app/app']
})
Problem
The problem is how these two apps, which again are both loaded on the page (this can't be avoided), are supposed to correctly look up these common modules.
Given that each of the apps have obviously a different baseUrl, they are put in different RequireJS contexts, otherwise the baseUrl of the second app would override the baseUrl of the first one, causing the incorrect loading of its modules:
// first-app/src/first-app.js
require.config({
context: 'first-app',
baseUrl: 'first-app/src',
})(['fist-app/app']);
// first-app/src/second-app.js
require.config({
context: 'second-app',
baseUrl: 'second-app/src',
})(['second-app/app']);
But putting them in context then causes the look up for the common modules to fail, as the modules are looked in the baseUrl of the context. Actually this happens only for the second app (second in order of loading), while the first app to be included in the page can load the common modules fine
Question
So how should I make the apps to correctly share the common modules? Am I approaching this wrong? Should I use something else than RequireJS?
The context feature of RequireJS is really meant to be used to handle a case where you have to load two conflicting applications on the same page and the conflict cannot be resolved otherwise. The way you've written your code so far may have led you to want to have two baseUrl values, but there is nothing in your question that indicates that you must have two baseUrl values. There are ways to avoid it:
Modules that are part of a logical set of modules should load each other with relative paths. For instance, the module you give as example could be:
// first-app/src/first-app/controllers/app-controller.js
define([
'../modules/controllers',
'../services/app-service',
'common/services/common-service'
], function (controllers) {
paths can be set to make it look like a module is directly under baseUrl even if it is not. You could have:
paths: {
'first-app': 'first-app/src'
'second-app': 'second-app/src'
}
and yes, loading first-app/app will work. RequireJS will transform the path to first-app/src/app.js.
I'm having a hard time getting the require.js build just right. I have a main module and then the other pages/modules are lazy loaded. When it's done compiling, I have to fix the compiled dist/main.js or the app will load the compiled main module from the dist folder, but other modules are still loaded from the app folder. I have to change the require.config baseurl from /app to /dist. What do I need to reconfigure to get it to build correctly?
Directory Structure
├── app
│ ├── modules
│ │ ├── example_module
│ │ ╰── another_module
│ │ ├── AnotherController.js
│ │ ╰── AnotherView.stache
│ ├── main.js
│ ╰── build.js
├── dist
│ ├── modules
│ │ ├── example_module
│ │ ╰── another_module
│ │ ╰── AnotherController.js
│ ╰── main.js
├── content
│ ├── css
│ │ ╰── main.css
│ ├── sass
│ │ ├── table.scss
│ │ ├── type.scss
│ │ ├── form.scss
│ │ ╰── main.scss
│ ╰── img
├── lib
│ ├── bootstrap
│ ╰── canjs
├── bower.json
├── gulpfile.js
├── package.json
├── README.md
╰── index.html
app/main.js
require.config({
baseUrl: '/app', // must change this after compilation!
paths: {
'jquery': '../lib/jquery/dist/jquery.min',
'jquery-easing': '../lib/jquery-easing-original/jquery.easing.1.3.min',
'jquery-throttle': '../lib/jquery-throttle-debounce/jquery.ba-throttle-debounce.min',
'jquery-inputmask': '../lib/jquery.inputmask/dist/jquery.inputmask.bundle.min',
'can': '../lib/canjs/amd/can',
'bootstrap': '../lib/bootstrap-sass-official/assets/javascripts/bootstrap',
...
},
shim: {
'jquery-easing': ['jquery'],
'jquery-throttle': ['jquery'],
'bootstrap': ['jquery']
...
}
});
require([...], function (...) {
// Init App
});
app/build.js
({
appDir: '.',
baseUrl: '.',
dir: '../dist',
mainConfigFile: 'main.js',
preserveLicenseComments: false,
modules: [
{
name: 'main',
include: [
'modules/dashboard/DashboardController',
...
]
},{
name: 'modules/example_module/ExampleController',
exclude: ['main']
},{
name: 'modules/another_module/AnotherController',
exclude: ['main']
},{
...
}
]
})
Interesting, I've actually not used this scenario with RequireJS, however this structure would make sense for bundles/progressively loading files.
What I've done in the past is one of two things:
1) Use the existing /app directory for progressively loaded modules. /dist would only contain main.js/css or output the minified files to the root(if it's only 1-2 files)
2) Re-create the entire structure with only necessary files inside /dist. For example: /dist/index.html, /dist/app/modules/*, /dist/main.js would all exist. This way you can copy the entire /dist contents to any deployment package you use, vs cherry-picking which files you'll need on a production server.
Typically, I've found #2 is more common in my experience.