Is there a way to include regular javascript files in the Firefox SDK background script?
If I just have a script file that defines some variables, include it and access those in the background script.
Its my understanding so far that they MUST be CommonJS modules. I am porting a Chrome Ext that also uses alot of common code with a mobile app, etc which I'd rather not try converting to CommonJS modules.
Is this possible?
Its my understanding so far that they MUST be CommonJS modules.
That's correct.
If you want to include standard JS files that are already structured in some way, you'd either have to inject them into a page worker, which will
Create a permanent, invisible page and access its DOM,
then send in and out the few variables needed and resulting, respectively, using port, as I explained in your last question.
Or you could use some sort of file concatenation (if you minify your files, this should already happen), then save this new JS file in the lib folder, and require/export those same variables.
These approaches only require you to input/output the variables that are needed externally from the system of files you already have in place, so it's less of a pain than converting each file to commonJS.
NB: I use Angular for my webapp, and have used some modules for both like so
var syncHelper = function() {
this.filter = function(objects, prop) {
// do stuff
}
this.consolidate = function(local, server, id) {
//more stuff
}
}
// app is my angular webapp var
if (typeof app==='undefined') syncHelper.call(exports);
else app.service('syncHelper', syncHelper);
Related
Nativescript Angular is well known for its code sharing properties. I am trying to simplify my design by using only 1 typescript file instead of splitting into the .ts and the .tns.ts file.
I was trying to import { Page } from "tns-core-modules/ui/page"; in the .ts. When running on Android, the code works flawlessly, but if I ng serve for the web app, it says Module not found: Error: Can't resolve 'tns-core-modules/ui/page'.
The reason why I wanted to import the page module is because of setting the action bar properties
constructor(private page: Page) {
if (isAndroid) {
console.log("This is Android");
this.page.actionBarHidden = true;
}
}
I was hoping to import the tns-core-modules/ui/page and some other tns-core-modules in the same file as the angular web app. Is it possible to do so? Or is it a must to split into the .ts and the .tns.ts files?
You have to go with platform specific ts files, one for web and one for tns, Page won't be valid while running inside a browser (ng serve).
If you prefer to reuse most of your code, try writting a common / base ts component, extend platform specific ts files from the common / base ts component, inject Page only within the tns specific ts file.
We are running 2 servers. Server 1 hosts a react application. Server 2 hosts a webcomponent exposed as a single javascript bundle along with some assets such as images. We are dynamically loading the webcomponent Javascript hosted on Server 2 in our react app hosted on Server 1. The fact that it is a webcomponent might or might not affect the issue.
What's happening is that the webcomponent makes uses of assets such as images that are located on Server 2. But when the react app loads the webcomponent, the images are not found as its looking for the images locally on Server 1.
We can fix this in many ways. I am looking for the simplest fix. Since Server 1 app and Server 2 apps are being developed by different teams both should be able to develop in the most natural way possible without making allowances for their app being potentially loaded by other apps.
The fixes that I could think of was:
Making use of absolute URLs to load assets - Need to know the deployed location in advance .
Adding a reverse proxy to Server 1 to redirect to Server 2 whenever a particular path is hit - Need to configure this. The React app could load hundreds of webcomponents, viz we need add a lot of reverse proxies.
Embed all assets into the single javascript on Server 2, like embed svgs into the javascript. - Too limiting. If the SVGs are huge and will make the bundle size bigger.
I was hoping to implement something like -
Since the react app knows where to hit Server 2, can't we write some clever javascript that will make the browser go to Server 2 whenever assets are requested by a Javascript loaded by Server 2.
If you download your Web Component via a classic script (<script> with default type="text/javascript") you can retrieve the URL of the loaded file by using document.currentScript.src.
If you download the file as a module script (<script> with type="module"), you can retrieve the URL by using import.meta.url.
Parse then the property to extract the base path to the Web Component.
Example of Web Component Javascript file:
( function ( path ) {
var base = path.slice( 0, path.lastIndexOf( '/' ) )
customElements.define( 'my-comp', class extends HTMLElement {
constructor() {
super()
this.attachShadow( { mode: 'open' } )
.innerHTML = `<img src="${base}/image.png">`
}
} )
} ) ( document.currentScript ? document.currentScript.src : import.meta.url )
How about uploading all required assets to a 3rd location, or maybe an AWS S3 bucket, Google Drive, Dropbox etc.? That way those assets always have a unique, known URL, and both teams can access them independently. As long as the names remain the same, so will the URLs.
To set the context I am creating a CRUD application for Laravel. It is installed via composer and the sources are therefore in the vendor/organization/package directory.
In my project, I use Datatable. So I use Laravel Mix to compile my sources and a command line allows to copy JS and CSS compiled files into the public directory of the Laravel Host application.
I would like however that the developers who will use my library can customize the display of some Datatable cells. To do this you must use Datatable's createdCell configuration.
$('#example').dataTable( {
"columnDefs": [ {
"targets": 3,
"createdCell": function (td, cellData, rowData, row, col) {
if ( cellData < 1 ) {
$(td).css('color', 'red')
}
}
} ]
});
The problem is that the JS sources of my project are already compiled...
For the moment I found a temporary solution that consists in leaving the JS sources in vendor/organization/package but copying the webpack.mix.js configuration into the Host application and asking the developers to compile themselves. The problem is that all JS dependencies must also be installed and it doesn't take very seriously to force the developers to compile sources before being able to use my library.
What are good practices to achieve this objective?
The following source may help, but I confess I don't know how to apply it to Laravel:
How to bundle vendor scripts separately and require them as needed with Webpack?
Thank you for your help.
I want to add a file(background.js) which is a background script for my firefox extension.
I added content scripts to my main.js using the following code.
var panel = panels.Panel({
contentURL: self.data.url("panel.html"),
onHide: handleHide,
contentScriptFile: [self.data.url("js/jquery.js"),
self.data.url("tipsy/jquery.tipsy.js"),,
self.data.url("js/settings.js")]
});
How do I add background scripts to the main.js file.
Simply place the file in the lib folder.
Except for scripts that interact directly with web content, all the JavaScript code you'll write or use when developing add-ons using the SDK is part of a CommonJS module.
Essentially, backend script don't share variables like content scripts/normal JS. You export and require variables between modules.
See adding local modules
I have YUI project that is mavenized. When we release new YUI code, it is not reflected right away in the browser, until you do SHIFT + REFRESH on browser.
I have been using YUI modules approach to load scripts like this:
YUI.GlobalConfig = {
modules: {
'manual-entry-util': {
fullpath: 'resources/js/common.js',
requires: [ 'node']
},
'user-perm-util' : {
fullpath: 'resources/js/userPermUtil.js',
requires: [ 'node', 'io-base', 'json', 'json-stringify']
},
'file-upload-custom' : {
fullpath: 'resources/js/fileUploadCustom.js',
requires: [ 'gallery-datatable-selection','event-custom', 'node']
},
'icsd-uploader' : {
fullpath: 'resources/js/icsdUploader.js',
requires: [ 'uploader', 'node']
},
'ui-util' : {
fullpath: 'resources/js/uiUtil.js',
requires: [ 'node']
}
}
};
I believe we need to modify the urls to have some sort of variable so that new code can be picked up by the browser.
Is there a way to automate this process via maven or some other tool. E.g. which can generate the hash value from the contents of the .js file and then add that to the url of .js file?
My approach has been to include a cache-busting value at the beginning of the path to your resources. An appropriate value might be the current abbreviated commit hash or revision number, or if using a CI tool, the current build number. Your build process would deploy all of your assets into a directory named with this value, so if your current commit hash was abcd1234, you would end up with files in something like resources/abcd1234/js/.
Your build process would need to also dynamically modify your YUI.GlobalConfig object, perhaps using token replacements, so that the YUI Loader could find your files there. This could be done in one spot by setting the base configuration option (see http://yuilibrary.com/yui/docs/yui/loader.html#configuration-options), but since you're specifying the fullpath for each file, you'd have to set each of these.
During development, you'd have to continue hard reloading your pages (as you're doing now with SHIFT + REFRESH), but your users will cache each version of your resources separately.
We use a variant of the answer from #blicksky. We built our own combo-loader as a servlet.
Firstly, we set up YUI as it's own Maven project. The version tag reflects the release of YUI, so your version would look like <version>3.17.2</version. We have an in-house repo, so any update to the YUI project gets published there. The YUI project just houses a copy of YUI in /src/main/resources/META-INF/resources. In this respect it's pretty similar to the approach taken by the WebJars project.
The Combo-loader takes care of concatenating the YUI files together for better loading performance and is also responsible for adding a cache-busting URL parameter. In production that parameter is the Build ID, but in development, that parameter can be a random number, so that the resources are loaded each time. We're using Spring on the server, so we use the Classpath to resolve YUI files that come from the YUI Maven project mentioned above. The basic gist is that our Servlet implements ResourceLoaderAware and can then use the ResourceLoader to pick up YUI files to serve up.
The approach has served us well and also allows us pretty fine-grained control of how the files are served, as well as improving load-times.