bundling a small task to make all dependencies available in puppeteer? - javascript

I have been personally using puppeteer for a lot of deployment and UI testing tasks.
But the issue I face now is that the more supporting code I have the harder to make it available directly in the browser.
What I usually do is that I place all the code I will use in the browser in a single file, encode the whole module as text, make it available to the browser and use a dynamic import in the browser. You see where I am getting, hopefully...
If I try to add 3rd party libs then this whole setup falls apart because I can't make all dependencies available in a single file.
Question is: Anyone has used any patterns for that? Is bundling an option here? any examples? Thanks a lot...

as I suggested in my inquiry above, one solution for external packages is to load them in through a CDN.
So
var scriptElm = document.createElement('script');
scriptElm.src = 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js';
document.body.appendChild(scriptElm);
You'd have to ensure that it is properly loaded before trying to use it, but that should be easy enough.
EDIT:
If I am using CDN's I might just as well import them directly to the consumer file ex:
import lodash from 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js';

Related

Managing configs for client-side npm modules - is there a preferred/standard way to go about this?

My primary question is whether or not the 'config' should be in a separate JSON/rc format, or if a general withCustomConfig-like function makes more sense. I realize this may be a matter of opinion, but I'm interested in hearing what more experienced developers think, as my searches for more information on this topic are coming up completely empty and I'm sure there's a preferred/standard way of handling something like this.
Essentially, I'm building an npm package for the generation/parsing of markdown for a specific use-case. The package allows for custom configurations to the characters utilized in the structure of the markdown itself. Originally, I was just intending on having users apply changes to the config via a simple withCustomConfig function (that accepts a config object); however, I started wondering if setting it via a JS function was not ideal - as the config's state then generally appears to seem more transient/loosely-defined than a completely separate rc or JSON config. I realize that is a matter of perception, but I think many people would share the same sentiment. And this poses a large risk because any changes to the configuration post-production would result in existing markdown becoming unparseable.
So, I started looking into having users configure a separate JSON config file. In order to import that into the browser, I realized I'd have to parse the JSON and convert it into a JS module before the user builds their client side application, which was relatively easy thanks to packages like fs. I set-up a small CLI utility to regenerate the JS module and added a postinstall script which parses the config file.
Then I started wondering if I was over-engineering this library, considering it's bound to be a relatively small aspect in its users' application. I started wondering if it even really warranted a completely separate config file and all the logic associated with parsing that for the browser. In general, would a simple withCustomConfig function actually be preferred/more-standard, or would an rc file be preferred by most people in this use case?

Grafana, write a simple plugin, without using grunt or whatever

Good day all. I'm new to Grafana and we adopted it very recently at work.
I'm willing to create a plugin, I need to load a simple external js library and fire it in a Grafana panel, nothing extreme.
First problem: I don't want to use any building library (grunt or whatever), I just want to write the plugin javascript, I don't want to redistribute it. Where do I write the code?
Am I right to write the code I want to execute in the data/plugins/myplugin/dist/ folder? (I'm trying to follow the steps at Grafana Docs, but they are unclear as they talk about building and install scripts which I don't like to use).
Second Problem: Seems like that if I use the dist/ folder, the plugin get executed. Now, I'd like to import a external.js library into it, the external library will take care of display the data as I like.
into my myplugin_ctrl.js I write this:
System.register(['app/plugins/sdk', 'lodash', './css/clock-panel.css!','./libs/datamaps'], function (_export, _context) {
var PanelCtrl, _, _createClass, panelDefaults, ClockCtrl;
As you may notice, I've used the clock plugin that is used into the how-to at Grafana.
I'd like to import './libs/datamaps', what I managed to do is having this error upon adding the panel to a dashboard:
Plugin component error Error: Fetch error: 404 Not Found
Instantiating http://127.0.0.1:3000/data/plugins/test-panel/libs/datamaps
Loading http://127.0.0.1:3000/public/plugins/test-panel/clock_ctrl.js
What I'm doing wrong? Where do the datamap.js should be? Or how do I can import it into Grafana plugin?
I don't know if you really need to solve this with a plugin, as I couldn't find any mention about data retrieval from any data sources in your question. Also, I'm not yet very familiar with Grafana plugin development, but I was able to solve one JavaScript related problem without a need to write a plugin.
What I did: I put a Text element in html mode on a dashboard and inserted a <script>...</script> section as well as some HTML code. This worked until I updated Grafana to a newer version, where they started to block this due to security reasons. After configuring /etc/grafana/grafana.ini setting disable_sanitize_html = true in section [panels], I made it work again. You could do this, too, but keep in mind that this is a security risk, because the dashboards now allow to inject any kind of malicious JavaScript code.
See also this Grafana reference page for scripted dashboards.

Webpack: How to have runtime (not buildtime) feature flags with same module names?

I'm hoping to find a way to have alternate versions of the same file available from the same webpack run and same output url, with a different chunk/bundle being dynamically loaded after a service call determines which group a user falls into.
Background:
Putting alpha/beta changes into production in the same build and output url lets us develop and test features with external users, but sticking conditionals everywhere (and later removing them) that needs can change is error-prone and generates more complicated code.
My thought was to have alternate versions of the same files in specially named subdirs - e.g. foo/file.js and foo/flagged--special/file.js - and then when something does import blah from 'foo/file' it will automatically get the correct version for that user.
This avoids conditionals in the code itself, and making a feature available for all is just overwriting the base file with the alternate. It also doesn't involve huge changes to our existing codebase and webpack config, nor does it involve a lot of funky and product-specific syntax to replace all our import statements. (After I put the idea together, someone pointed me to Mendel, where Yahoo did much the same thing, albeit as their own framework that is not friendly with webpack, so I'm assuming the base idea isn't crazy)
Problems:
I see examples of feature-flagging a build to one version or the other, but not any examples of having both in one build.
I could write a custom loader or plugin to wrap each file load to do this (I think - not sure about how the output of webpack works in terms of runtime evaluation), but that would result in adding both versions to the bundle.
I'm thinking I can create a base output chunk that does little more than fetch the user's options, then dynamically load one of two alternate chunks that have the different versions...but I have no idea if that will work, or if I'm fighting a losing war vs the webpack internals.
Can this work?
Has someone already done this?
Is there a better way?
Thanks in advance!

How to organize Vue-JS : Non Javascript way?

How to organize Vue-JS project [files and directory]: Non Javascript way?
Coming from a non-javascript background, I found Vue.js very intuitive and easy to use. My earlier experience in Javascript is with JQuery and vanilla javascript on the browser.
I created an application using Vue , Vue-components and vue router. Everything works fine.
My problem is, I have ended up writing a lot of code in a single index.html file of my project. This file contains over 10 templates that I have created and attached to different component in my app. I want to know that is there a non-javascript way to organize these templates in seperate files.
I see that there are options using webpack and browserify to modularize the project. But coming from non javascript background, I don't find them intuitive. I don't want to go node - npm way because that has its own learning curve and moreover it downloads a dozen of files and dependencies in my project which I don't understand. I am old school and more comfortable downloading the files and including them in the webpages.
So probably, you understand where I am going to. I need a solution where I could put my templates as separate files and read those files in the different components.
What I have tried :
Declaring the templates inside my components. But writing all that html inside the component is not that clean. It also, makes my JS file too huge. I am better in putting all data in the index.html instead.
Storing template as smaller chunk "homepage.html","about.html" and in my components, using $.get / $.load to read different components in ready function of the component. This works but I still have to fire an additional ajax call for each component which is not efficient.
Please refrain from suggesting the obvious node-npm [webpack and browserify] way. I know thats what is supported by Vue but this needs a learning curve and complete setup. Answer to this question would actually help other developers who hesitate going the node-npm way.
Please shout back if you need more clarifications to the question.
The options you've mentioned are your only real ones... the HTML of the template needs to be available when it's needed, so you either have to have it within your html file off the bat, or load it using AJAX or an in-browser loader like RequireJS (and this extension that allows it to load HTML https://github.com/requirejs/text).
In-file templates make sense for very small projects. As your project grows, you'll need to start using the tools that are built for this. NPM rocks and every JS package that you'll ever need can be included in your project in seconds.
I highly encourage you to try the Vue CLI
It does use node, npm, webpack and downloads dozens of files. Which you've you've explicitly asked for not to use, so let me clarify:
The Vue CLI takes care of the complexity and configures webpack for you.
You don't even have to know it's using webpack.
It's very developer friendly (it even has a built-in gui) and lowers the barrier to entry compared configuring a webpack config.
I hope you'll also find it "intuitive and easy to use".

How to update HTML script and link references when combining JavaScript and CSS files?

Multiple sites reference combining JavaScript and CSS files to improve web page performance, including examples of using ANT build scripts to concatenate the files prior to deployment.
I've search, and haven't found any information how to automate updating references to those files in HTML and other documents. I am looking to avoid hacking together something error prone, and want to learn from others who have automated builds in the past.
Are there automated tools in the wild to complete this task that I'm not seeing? Are there recommended processes to update the script and link tags in HTML? Can these solutions be integrated with ANT or similar build tools?
There sure is and it's a smart thing to do.
I found a PHP solution, don't know it that's okay for you, but if it isn't you can still read it's source (it's not difficult) and learn a lot. The solution works like this:
Rewrite your requests like this: from css/main.css and css/skin.css to css/main.css,skin.css (of course you can put many more).
Use apache's mod_rewrite to redirect this request to a script (in our case combine.php), that will combine all files to a single one.
The script combines all the files and sends the combined file. Then it saves it to a cache folder.
Next time around it checks if there is an up-to-date version of the cache and serves that one. If the latest file modification time has changed, it discards the cache.
The solution works great and it even makes use of HTTP cache headers and spits out an [ETags], which you should do anyway.
You are correct this is a great way to speed up page loading. It will even work in conjunction with a CDN, which the other poster recommended.
Here is a small script that will pack multiple files in to one for deployment. It supports both JS and CSS, and will even "minify" them by removing whitespace, etc. Just hook this in to your build and deploy scripts.
juicer: http://cjohansen.no/en/ruby/juicer_a_css_and_javascript_packaging_tool
What even better, it will follow JS and CSS import statements, so you only need to point your HTML files to the loader file and it will work in both development and production. (Assuming you replace the loader file with the combined file on deployment.)
There are others, including some run-time solutions. But it sounds like you have a build process in place anyway.
As far as HTML updating, if you still need it, since automated deployments are very popular in the Ruby world, and you may find some standalone utilities to help even for non-ruby projects. (As above) Methinks this would be best handled by your own project's template language, though. (With a static resource revision id, or such.)
Good luck, and let us know what you find.
I think what you really want is a CDN Content Delivery Network.
Read about it here
http://developer.yahoo.com/performance/rules.html
http://en.wikipedia.org/wiki/Content_delivery_network

Categories