How to automatically include js/css file? - javascript

In normal web project, we have to inlcude js/css file like this:
<link type="text/css" rel="stylesheet" href="/css/main.css" />
<script type="text/javascript" src="/scripts/js/main.js"></script>
whenever we add a new css file or js file we have to add one more line.
In Meteorjs, its automatically taken care by Meteor itself, but for non-meteor project, can we do that?
for example, I just put any js file into js folder and I don't need to care about it anymore.

use the "browserify"
in the "package.json"
..."scripts": {
"build": "browserify public/javascripts/main.js > public/javascripts/main-build.js",....
in the "main.js"
var ObjectName = require('./another_file');
html
<script src="javascripts/main-build.js"></script>
another_file.js
ObjectName = function(){ ..... }
module.exports = ObjectName;

Related

What is the correct way to add a NPM package to a Laravel 9 project with Laravel Mix?

Laravel Mix introduces itself as
An elegant wrapper around Webpack for the 80% use case.
I believe I have a widespread use case, and I want to know if the 80% covers this and how to do it right. It could be any other package, but I have editor.md as an example. They want you to install it with npm i editor.md and use it like the following.
<link rel="stylesheet" href="editor.md/css/editormd.min.css" />
<div id="editor">
<!-- Tips: Editor.md can auto append a `<textarea>` tag -->
<textarea style="display:none;">### Hello Editor.md !</textarea>
</div>
<script src="jquery.min.js"></script>
<script src="editor.md/editormd.min.js"></script>
<script type="text/javascript">
$(function() {
var editor = editormd("editor", {
// width: "100%",
// height: "100%",
// markdown: "xxxx", // dynamic set Markdown text
path : "editor.md/lib/" // Autoload modules mode, codemirror, marked... dependents libs path
});
});
</script>
Now I want to know how to get the following paths right.
editor.md/css/editormd.min.css
jquery.min.js (not a dependency)
editor.md/editormd.min.js
editor.md/lib/
My ideas/questions:
I could copy the CSS and JS files with Mix.
mix.copy("node_modules/editor.md/css/editormd.min.css", "public/css/editormd.min.css");
mix.copy("node_modules/editor.md/editormd.min.js", "public/js/editormd.min.js");
But then I miss all the files from the lib folder (4th path). I could copy this folder as well. I could copy the entire node_modules/editor.md folder to my assets folder, but this feels too much. And finally, where is jQuery coming from? Do I add it from a CDN? Do I install the npm package? Again, I saw solutions requiring everything in the app.js file.
How to do it the right way?
For Laravel Mix, the correct way to implement this is to run the following.
npm i editor.md jquery
Then add your require() methods in the bootstrap.js file.
resources/js/bootstrap.js
window._ = require('lodash');
try {
window.$ = window.jQuery = require('jquery');
window.editormd = require('editor.md');
} catch (exception) {
console.error(exception);
}
In your template, likely located at /resources/views/layouts/app.blade.php, you will need to add the following at the bottom of the file before the closing </body> tag.
<script src="{{ mix('js/app.js') }}"></script>
This may not be the best way to do it, but you could copy the entire directory with mix.copyDirectory(srcDir, destDir) as seen here

How to keep an absolute path unchanged for a script tag in index.html with Vite

With Vite, using absolute paths in index.html results in them being transformed based on the base config, which is nice.
For instance my index.html contains this:
<script type="text/javascript" src="/config.js"></script>
And base is set to "/demo". The exported index.html will contain:
<script type="text/javascript" src="/demo/config.js"></script>
This is fine for most of my file but I would need to have a script loaded from the root of the server for a very specific thing. Is it possible to indicate to Vite to not change the path of a specific script tag? Like a preprocessor command? Like this:
<!-- #vite-ignore -->
<script type="text/javascript" src="/config.js"></script>
That would be nice!
I used an ugly fix:
<script type="text/javascript">
// We have to do it using javascript otherwise Vite modifies the path
var config = document.createElement('script')
config.type = 'text/javascript'
config.src = '/config.js'
document.head.appendChild(config)
</script>

Can't call any Blockly methods in index.html even though it works in other .js files and a workspace is shown

I'm trying to create a tool where you can create HTML pages using Blockly blocks. I already have a page that shows my workspace and my self-created block. Now I want to write a script that gets the code from the workspace. Normally there is a workspaceToCode method in the Blockly library. Unfortunately I can't access any Blockly methods or really anything Blockly-related in my index.html.
I've looked up similar projects and can't seem to find any differences. I'm loading blockly_compressed.js, blocks_compressed.js and javascript_compressed.js. And because it shows me a workspace with "functioning" blocks I'm pretty sure that the paths are correct.
See below what I tried and thanks in advance for your help:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="styles.css">
<style>
...
</style>
<script src="node_modules/blockly/blockly_compressed.js"></script>
<script src="node_modules/blockly/blocks_compressed.js"></script>
<script src="node_modules/blockly/msg/en.js"></script>
<script src="node_modules/blockly/javascript_compressed.js"></script>
</head>
<body>
...
<script src="html_blocks.js"></script>
<script src="html_generator.js"></script>
<script src="main.js"></script>
<script>
function update(event) {
var code = HtmlGenerator.workspaceToCode(workspace);
document.getElementById('HTMLCodeDiv').innerText = code;
}
workspace.addChangeListener(update);
</script>
</body>
</html>
The error it is giving is "unresolved function or method" for the workspaceToCode method as well as the addChangeListener method.
Since you haven't shown all of your code, I can't provide a precise answer to explain exactly what's gone wrong for you here, but I can say that Blockly in a classical (non-module) script tag adds itself to the window as follows:
// ...
} else { // Browser
var factoryExports = factory();
root.Blockly = factoryExports;
}
// ...
where root is window (by way of this) and factory() is the entire Blockly code. All Blockly functions are namespaced inside of the window.Blockly object, so there is no such window.workspace variable that would be created unless one of your other scripts (not shown) created this and attached it to the window.
If you open your browser console, you can type Blockly. and see the list of available properties that were imported by the scripts. The other Blockly scripts simply attach more properties to the global Blockly object that was created by the first script tag. Blockly.Workspace and Blockly.workspaceToCode are some of these properties, and you can call Blockly.inject to create a workspace.
For example,
const blocklyWorkspace = Blockly.inject("blockly-container", {
toolbox: document.getElementById("toolbox")
});
document.querySelector("button")
.addEventListener("click", e => {
const code = Blockly.JavaScript
.workspaceToCode(blocklyWorkspace);
console.log(code);
});
#blockly-container {
height: 100vh;
}
xml {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/blockly/8.0.0/blockly.min.js" integrity="sha512-m19pjKFpHlhFqUAWB49IQt7ip1P7UDKyV0k0f7UGnN8pXSLFjtvsrRcDlwRw+ZhaNeqQTwHwE9+CJgPAWUyA9Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<button>Workspace to code</button>
<div id="blockly-container"></div>
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox">
<block type="text_print"></block>
<block type="text"></block>
</xml>
It strikes me as an antipattern to use node_modules in script tags like this, even though some of the Blockly examples do this. Usually, you'd use a bundler of some sort (webpack, parcel, vite, browserify, rollup, etc) to allow you to dynamically import the code using modules (example below). Or else keep your build without any local dependencies and use a CDN and take advantage of client caching (as shown above). Using node_modules directly seems like the worst of both worlds, especially without a minification build.
For example, you can use parcel to build your app for the web. A bundler makes it easy to use node_modules without specifying the paths. You can develop using modules rather than legacy UMD script tags, which help you organize the project into chunks and avoid polluting the window with shared data.
The example below is contrived for clarity, but hopefully you can extrapolate the approach (or something similar) to your project.
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
#blockly-container {
height: 100vh;
}
xml {
display: none;
}
</style>
</head>
<body>
<div id="blockly-container"></div>
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox">
<block type="text_print"></block>
<block type="text"></block>
</xml>
<xml xmlns="https://developers.google.com/blockly/xml" id="start-blocks">
<block type="text_print" id="N4+B!H6xh[=wx]z^LqGk" x="38" y="38">
<value name="TEXT">
<shadow type="text" id="~uw6Vr9}hxZS-=a(Zjt{">
<field name="TEXT">hello world</field>
</shadow>
</value>
</block>
</xml>
<script src="src/index.js" type="module"></script>
</body>
</html>
src/index.js:
import Blockly from "blockly";
import generateCode from "./generate-code";
const blocklyWorkspace = Blockly.inject("blockly-container", {
toolbox: document.getElementById("toolbox")
});
Blockly.Xml.domToWorkspace(
document.getElementById("start-blocks"),
blocklyWorkspace
);
console.log(generateCode(blocklyWorkspace));
src/generate-code.js:
import Blockly from "blockly";
export default blocklyWorkspace =>
Blockly.JavaScript
.workspaceToCode(blocklyWorkspace);
package.json:
{
"scripts": {
"start": "node node_modules/parcel/lib/cli index.html"
},
"dependencies": {
"blockly": "^8.0.3"
},
"devDependencies": {
"parcel": "^2.6.2"
}
}
Building and running:
npm i
npm start
Now, navigate to (by default) http://localhost:1234 (or whatever parcel tells you on the console) and begin developing.

Where i can place timeline.js in my app? For gtmetrix

<link rel="stylesheet" href="/src/common/timeline/timeline.css">
<script defer src="/src/common/timeline/timeline-min.js"></script>
I want to place this to code in my project for compile and compress to save place and update speed.
But i have an error
How to do it correct?
Why not keep the file on same level as index html?
public/
index.html
timeline.js
timeline.css
And in index.html use like
<link rel="stylesheet" href="./timeline.css">
<script defer src="./timeline.js"></script>
If you want to keep the files somewhere else (say src folder) and manage using it using webpack, you can use copy-webpack-plugin
const CopyPlugin = require("copy-webpack-plugin");
plugins : [
// Some other plugins
new CopyPlugin([
{ from: "./common/timeline/timeline.css", to: "./timeline.css" },
{ from: "common/timeline/timeline.js", to: "./timeline.js" }
])]
And refer the files using the same code as before
<link rel="stylesheet" href="./timeline.css">
<script defer src="./timeline.js"></script>

What regex can I use to match CSS and JavaScript links in an HTML document?

I'm using a simple gulp task for "minifying" my CSS and JS files. The task adds a .min suffix to the name of the minified files. I'd like to update the HTML to point to the new, compressed files e.g:
Change this:
<link ... href="...some_name.css ..." ...>
To this:
<link ... href="...some_name.min.css ..." ...>
I use gulp-string-replace plugin, but I can't figure out the right regex to target JS and CSS links. I don't want to hardcode filenames and I obviously can't just match for the strings .css or .js.
Sample tasks:
var replace = require('gulp-string-replace');
gulp.task('replace_1', function() {
gulp.src(["./config.js"]) // Any file globs are supported
.pipe(replace(new RegExp('#env#', 'g'), 'production'))
.pipe(gulp.dest('./build/config.js'))
});
gulp.task('replace_2', function() {
gulp.src(["./index.html"])
.pipe(replace(/version(={1})/g, '$1v0.2.2'))
.pipe(gulp.dest('./build/index.html'))
});
gulp.task('replace_3', function() {
gulp.src(["./config.js"])
.pipe(replace(/foo/g, function () {
return 'bar';
}))
.pipe(gulp.dest('./build/config.js'))
});
This would solve your question, but would include all css file links.
replace(/href=\"(\S*)\.css\"/gi, 'href="$1.min.css"')
The usual way to do this would be to incorporate something like the gulp-processhtml
plugin in your workflow. It is designed to do exactly what you are doing.
<!-- build:css style.min.css -->
<link rel="stylesheet" href="css/style.css">
<!-- /build -->
becomes simply
<link rel="stylesheet" href="style.min.css">
Here is a gulp 4.0 task I use when moving a development version of the html to a deployment directory:
var stripComments = require("gulp-strip-comments");
var modifyHTMLlinks = require("gulp-processhtml");
var addVersionString = require("gulp-version-number");
var print = require('gulp-print').default;
function processHTML() {
return gulp.src(paths.html.src)
.pipe(print())
// modifyHTMLlinks: remove browserSync script link
// update css/js links to .min.css or .min.js
.pipe(modifyHTMLlinks())
.pipe(stripComments.html(stripOptions))
// add ?v=dateTime stamp to css and js links
.pipe(addVersionString(versionConfig))
.pipe(gulp.dest(paths.html.deploy));
}
This seems much more foolproof than messing with regex's but perhaps you have some reason to avoid such a plugin?

Categories

Resources