How do I load CSS & JS into Sails.js layout based on the route? - node.js

I have a Sails.js 0.11.0 application with a master layout.ejs file. Right now, I am using the standard asset pipeline and loading all my CSS & JS by dropping them in the assets/styles and assets/js folders.
The issue with this approach is that the application loads ALL the CSS & JS files relevant to the site regardless of whether the page that is being rendered needs it or not. I would like to be able to load specific CSS & JS files based on the page while leaving the common stuff to still get loaded through the asset pipeline. How do I go about doing that? I couldn't find any documentation to get this done.

In production, everything should be getting minified so you won't be getting the multiple server hits that you are probably experiencing. Thus pull one style sheet and one js file.
If you really wanted to make this work though you could disable using the layout and include in each view the actual files you want to include, but you lose a few things with this approach.
-If you run through the Sails.js pipeline the files won't be auto added or removed when you add them to the js folder
-Minification will break your application so you would need to manually setup your own build process to properly handle or disable minification.
Hope this helps.

Create a local folder assets/js/local to store any scripts that you might want to load separate to the pipeline.
Then in your tasks/pipeline.js file add the '!js/local/*.js' line to ignore any script files in the local folder.
var jsFilesToInject = [
// Load sails.io before everything else
'js/dependencies/sails.io.js',
// Dependencies like jQuery, or Angular are brought in here
'js/dependencies/jquery-3.3.1.min.js',
'js/dependencies/popper.min.js',
'js/dependencies/**/*.js',
// All of the rest of your client-side js files
// will be injected here in no particular order.
'js/**/*.js',
//Ignore local injected scripts
'!js/local/*.js'
];
In your views/layout.ejs template add a block under the SCRIPTS block...
<!--SCRIPTS-->
<script src="/js/dependencies/sails.io.js"></script>
<script src="/js/dependencies/jquery-3.3.1.min.js"></script>
<script src="/js/dependencies/popper.min.js"></script>
<script src="/js/dependencies/bootstrap.min.js"></script>
<script src="/js/scripts.js"></script>
<!--SCRIPTS END-->
<%- blocks.localScripts %>
In your page view template call your file/s...
<% block('localScripts', '<script src="/js/local/myLocalScript.js"></script>') %>
<div class="container">...</div>

Related

How to add external js files in shopware6.4

i am new in shopware 6.4.
I want to subscribe newsletter for that i try to import external js file.
Can anyone have idea about how to import external js file in plugins.
any clue have great help for me.
https://developer.shopware.com/docs/guides/plugins/plugins/storefront/add-custom-javascript is more about importing javascript files that you have locally.
If your script is hosted by a 3rd parts, one option would be to use
<script src="https://example.com/external-js-file.min.js"> in your template.
You can extend the block
{% block layout_head_javascript_feature %}
and add your script tag there.

WebpackHTMLPlugin output built references with a prefix

I have a configuration option for my Express app that determines whether to pull static content (JS, CSS, etc.) from a separate URL (e.g. using webpack-dev-server) or serving it "inline" via express.static() in the Express app. So I need to output a different origin depending on that configuration:
<script src="{STATIC_CONTENT_PATH}/[resource reference]"></script>
where {STATIC_CONTENT_PATH} is the web server's origin if serving inline, or the content server's origin if running separately. So far, I've only been able to get it to output a path that is relative to the site root (/publicPath/[resource reference]). Is there an easy way to add a prefix to the path used in the tags that the plugin outputs?
I don't think there's any existing option to do this, so I just used a template, which contains the following:
<%= _.map(htmlWebpackPlugin.files.js, (path) => `<script src="${htmlWebpackPlugin.options.staticContentURL}${path}"></script>` ).join("") %>
(I also passed through the URL as a config option to the plugin)

Route static page with vue-router

I'm fairly new to web development and I was wondering if there was a way to route a static web page with its own stylesheets and javascripts, using vue-router.
Let's say I have a directory called staticWebPage that contains:
an index.html file
a javascripts directory containing .js files
and a stylesheets directory containing .css files
Now, I'd like to map /mystaticwebpage to this index.html file so it displays that particular static web page.
I'd like to do something like this:
import VueRouter from 'vue-router'
import AComponent from './components/AComponent.vue'
import MyHtmlFile from './references/index.html'
router.map({
'/acomponent': {
component: AComponent
},
'mystaticwebpage': {
component: MyHtmlFile
}
})
Of course, this doesn't work as I can only reference Vue components in router.map.
Is there a way to route to that ./staticWebPage/index.html file using all the .js and .css file contained in the /staticWebPage directory?
So for your case you can do something that uses Webpack’s code-splitting feature.
More precisely, what you want is probably async components. So the code (and the css) used in the component definition (including any script you included there) will be loaded only when the corresponding page is accessed.
In large applications, we may need to divide the app into smaller
chunks and only load a component from the server when it’s actually
needed. To make that easier, Vue allows you to define your component
as a factory function that asynchronously resolves your component
definition. Vue will only trigger the factory function when the
component actually needs to be rendered and will cache the result for
future re-renders.
It can be a bit challenging to setup, so please refer to the dedicated guide in the VueJS doc.

Sails.js: can't find variable require (react-bootstrap-datetimepicker)

I'm using Sails js and I want to use a nodejs module.
I also use React js.
I want to use react-bootstrap-datetimepicker in my javascript script.
react-bootstrap-datetimepicker
I installed my module with npm install react-bootstrap-datetimepicker
I tried in config/boostrap.js to add this line var DateTimeField = require('react-bootstrap-datetimepicker');, but DateTimeField isn't recognised in my js script.
Uncaught ReferenceError: DateTimeField is not defined
I also tried to add this line directly in my script, but I have this error:
ReferenceError: Can't find variable: require
And also this one in my script: import DateTimeField from "react-bootstrap-datetimepicker";
I have all these errors in the navigator console.
EDIT 1:
I understand what you said, thank you for your answer.
BUT, for example with react-bootstrap, I can use:
var Input = ReactBootstrap.Input;
var ButtonInput = ReactBootstrap.ButtonInput;
There is exactly the same architecture with react-bootstrap-datetimepicker, so I maybe I can do the same?
var DateTimePicker = ... . DateTimePicker
I tried to include like you said, but it doesn't recognise DateTimePicker.
Here is the doc:
Installation :
npm install react-bootstrap-datetimepicker
Then
javascript
var DateTimeField = require('react-bootstrap-datetimepicker');
render: function() {
return <DateTimeField />;
}
See (examples/) for more details.
And in examples/, the line is:
import DateTimeField from "react-bootstrap-datetimepicker";
Ok, first you have to understand the division of server side and client side javascript, even thought you are using the same language, and you can share libraries, bare in mind, that for client side js you need to supply the user browser with the libraries and scripts it needs, so those have to be in the html you serve the user. When you require any module in sails bootstrap or similar, you are loading the script into the server memory, not serving it to the users browser, that means you can use in the server code, but not in client code.
For you use case, you have to download the library code, and put it in your assets/js folder and if you have the script tags in the layout, sails will automatically inject it there for you, but if not or you are using other template engine like jade, just manually add it.
example:
<html>
....
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/<react-version>/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/<react-version>/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-bootstrap/<version>/react-bootstrap.min.js">
<script src='/js/react-bootstrap-datetimepicker.min.js'></script>
// The other js files that depend on datetimepicker go here
</html>
Now just to be clear, require is a node.js function, node.js is not the same as javascript, its a piece of software with its own functions, thats why you are getting an error related to it when trying to use it in the browser, there is no require method there, so you can't use it, at least not directly. You can use browserify to sort of emulate the node workflow, where you have a node_modules folder and use require on those, browserify will bundle (search for the modules and merge them) and give you a javascript file that you can then link in your html code. That is more setup work, and unless you really need it, because you have a lot of files, i think is not worth the effort.. lets say for just one file using require.
So i think you were misguided by that github repo, because it says npm-install. Just ignore it (unless you use browsefify like i said) and download the link i gave you above ( the .min.js).
So to sumarize, you issue have nothing to do with sails, just link the library in the html you provide to the user, like any other client side script.

Why can't I require files which are available due to app.use?

If a directory has been made available to a node application in the server.js file which sits in the main directory using:
app.use("/scripts",express.static(__dirname + "/scripts"));
and I attempt to use require from a file inside of that directory (/scripts/custom.js) using:
var Testing123 = require('../app/models/article');
Is there a reason this is not possible? and is there a solution to that problem?
Edit: In one of my views (views/tree.ejs) I use:
<script type="text/javascript" src="../scripts/custom.js"></script>
to access my Custom script which sits inside my scripts folder which is made available using express.static, Custom uses a web scraper to scrape articles and present them in circles (in the form of an image, title and link) on views/tree.ejs, I now want custom.js to save each article it creates to a mongodb database but to do so, it needs access to things like my Article Schema hence the problem above.
You cannot because Node.js scripts and browser scripts do not run in the same context. Your app.use call just exposes a /scripts route that serves assets statically on your HTTP Server.
Your scripts/custom.js script seems to be a browser-side script (Because you load it with a script tag inside an ejs view) but you want to use require inside it and this will not work as this is a Node.js function.
Have a look at LearnYouNode which is an excellent Node beginner tutorial so that you will understand how modules work in Node and know a bit more about the separation between server-side and client-side JS.

Resources