Adding a houdini paintworklet in a nuxt3/vue app - vue.js

I am trying to add a paintworklet to my application, but I am having a really hard time.
The worklet is a npm dependency, but worklets can't be inlined, they need to be registered like so:
CSS.paintWorklet.addModule('url/to/module.js');
I am having a hard time, because even though that currently works in my application, I am not sure if this is the right way to go about it, or if it will work in production. Currently, my url points to a file inside node_modules and I am not sure if nuxt will do anything with this.
I am currently doing this with a .client.js file inside the plugins folder. But they need an export default function(), but the worklet code does not have an export.
What I am currently trying to do, is tell nuxt somehow to grab certain files from node_modules and serve them as assets somehow, and then reference them some other way. But I cannot find any resources on this.
Any ideas would be appreciated.

If the file path is specified in a literal string, containing node_modules, the paint worklet might appear to work in development mode, but the worklet file will not be bundled in the build output:
CSS.paintWorklet.addModule('./node_modules/extra-scalloped-border/worklet.js')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
❌ file not bundled in build output
Solution: Import the file
Importing a file enables the bundler to track the file, and include it in the build output. Nuxt 3 uses Vite by default, and the Vite docs describe how to import the file to use with paint worklets:
Explicit URL Imports
Assets that are not included in the internal list or in assetsInclude, can be explicitly imported as an URL using the ?url suffix. This is useful, for example, to import Houdini Paint Worklets.
import workletURL from 'extra-scalloped-border/worklet.js?url'
CSS.paintWorklet.addModule(workletURL)
Since the CSS.paintWorklet API is only available in the browser, make sure to use this in the mounted() hook, which only occurs client-side:
import workletURL from 'extra-scalloped-border/worklet.js?url'
export default {
mounted() {
CSS.paintWorklet.addModule(workletURL)
}
}
demo

Related

Not sure how to preview my generated Nuxt3 app

I've just created a Nuxt3 in static mode but I don't want to push it to Netlify everytime to preview it.
Here is my nuxt.config.js (nothing changed)
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
})
Also, I don't know why but yarn generate is not working as you can see below, it says
Preview is not supported for this build
Opening the index.html file directly is not helping because I do have a lot of errors + my API calls are not working.
If you want to preview your statically generated content, you will still need a light server to serve the assets + handle the API requests etc.
Even host providers like Netlify/Vercel do run a small server to serve static files.
The fastest solution is probably to use serve, you don't have to install it directly on your system (I didn't achieved to make it work myself).
You can run npx serve .output/public to have something working in no time and get a functional preview.

How to use static JS with Vue CLI?

I'm creating a Bootstrap Vue application (built with Vue CLI), and there's a Javascript library I want to be able to utilize: https://nadchif.github.io/html-duration-picker.js/. I tried putting the file in /assets and then using import in the script portion of App.vue (import './assets/html-duration-picker.min'), but I have not been able to get the script to work, not sure why (nothing happens, no duration picker shows). As an alternative, I thought I could maybe simply load the library in the traditional way in the head of index.html. But I'm not clear what the src URL should be for a file in the assets directory. Or should it be in the assets/public directory?
Honestly, you might as well use the npm package, if you are using Vue CLI, to save yourself a lot of trouble:
npm i html-duration-picker
DOCUMENTATION.md is where the installation instructions lie. While there aren't any for Vue, there are instructions for Angular, and it's fairly easy to get it working for Vue.
Just import html-duration-picker:
import * as HtmlDurationPicker from "html-duration-picker";
...and initalize it in mounted():
mounted() { HtmlDurationPicker.init() }
You can also run HtmlDurationPicker.refresh(); to "update dynamically loaded input boxes." I don't think this is necessary if you use v-model to bind the boxes' values to data properties which update fine from either end.
Here's a sandbox you can check out for more info.
If you do want to import it manually from assets, though, then what you're doing is probably fine (though you might need to add the .js to then end of the path); you'll just have to initialize it.

How to publish a vue js plugin that modifies an existing plugin

I am trying to create a plugin that utilizes components from another Vuejs plugin (Vuetify). Basically, I have some common components I want to share across multiple applications with our company.
I thought it would just be a matter of:
Create a github repo for the shared components
Author the plugin
Reference the repo in consuming apps via npm install
Here is the gist of the plugin:
// src/index.js <-- package.json/main is set to "src"
import MyComponent from "./MyComponent.vue";
import * as api from "./api";
export default function install(Vue) {
Vue.component("myComponent", MyComponent );
Vue.prototype.$myApi = api;
}
At the moment, the behavior I'm seeing is:
GOOD
plugin install function is being executed
functions from api attached to Vue.prototype are available in app components
my-component is available in the app and renders markup
BAD
$myApi and Vuetify components are not available in an application instance of of my-component
If I copy the same files into the app and change my import, all works as expected. So, I now wonder if I'm missing something regarding sharing code via external modules.
I've tried these alternatives with the same issue:
use npm link to link the plugin module to the app
manually, use mklink (Windows sym link) to link plugin module to node_modules in the app folder
use a long relative path reference to the plugin module: import MyPlugin from "../../../my-plugin"
I've put this issue off for a while, but for anyone wondering, the issue is with using Single File Components and webpack not compiling those in external modules.
The 2 options I have are:
Don't use Single File Components. I.e.: Just use .js instead of .vue. I've seen some libs like Vuetify.js take this approach
Compile the .vue files in the library module and include them in the source such as ./dist folder.

How to access npm-installed package in hexo app

I am creating a web app using Hexo. I want to use a package called slick-carousel in one of my pages. This package also contains jQuery by the way. So I successfully installed (and "--save"ed) the package via npm. The package shows up in my node_modules folders and on my package.json file.
I expected that after doing this, I should have access to both jQuery and slick functions in my markdown files, but I don't. When I render the generated page on my browser, I am told that 'jQuery is undefined.' What step am I missing here so that I can actually use my installed packages?
Here is the script tag I added to my markdown file that I am trying to make work:
<script>
jQuery(document).ready(function(){
jQuery('.carousel').slick({
dots: true,
infinite: true,
speed: 300,
slidesToShow: 1,
centerMode: true,
variableWidth: true
});
});
</script>
I am still trying to fully grasp the relationship between installed packages and the rest of my application, so forgive me if this question doesn't even make sense. Any insight or explanation you can give me would be much appreciated!
Just because the scripts are in node_modules, doesn't mean they are automatically added to your projects frontend.
There are different ways to achieve what you need:
Manually moving the assets
Instead of trying to fiddle around with package.json and module requirements, the probably easiest way to get what you want is
moving the distribution files of jquery and slick-carousel out
of the node_modules folder into a folder where Hexo can work with
them better (after a quick read-up it should be source) then you
just link your JS file in your HTML layout and everything should work fine
Automatically moving the assets
With using some kind of task toolkit (like Gulp or Grunt) you could write tasks that automatically move the assets out of the node_modules folder inside a folder that is accessible by Hexo, a Gulp task could look something like this:
gulp.task('jquery', function () {
return gulp.src('./node_modules/jquery/dist/jquery.js')
.pipe(gulp.dest('./source/js'))
})
Using require (if supported)
I never used Hexo before, so I have no idea of it's internals, but sometimes it might be possible to just use require in the Javascript files to load modules that were downloaded, so you could use
window.jQuery = window.$ = require('jquery')
for example, to directly load the script as module.
You might need to test this yourself, but these are probably the three most common ways to handle assets in Node.js projects.

Aurelia Element Loading Issues

Our environment has setup a private git repository and configured jspm to install packages from this repository. The repo has a .js, .html, and .css file. Jspm brings all the files down into a folder with #master appended to the name to reflect the branch and stores it all in the pre-configured jspm_packages location on my machine. It also adds a second #master.js file next to the folder with export statements inside (I didn't create this file myself).
These files represent custom elements I want to use in my aurelia application. There is a .js for the viewmodel and a .html for the view (and a .css file). When I go to use the custom element I get a 404, file not found, because system.js is looking for a #master.html file, which doesn't exist.
Jspm seems to be referencing the #master.js file in config.js and somehow that's assuming a #master.html file in Aurelia? Only a #master.js file was created when I installed the package using jspm. The original .html file does exist and lives inside the folder I mention above, but that #master.html file does not and I'm not sure 1) what that file would be for and 2) why it's being referenced. There no reference to #master.html in my code.
I'm not really even sure if this is a JSPM issue, Aurelia issue, System.js issue, or some combination of them?
Anyone else have a similar experience with these technologies?
Thanks,
Chris
Essentially, Aurelia believes you are importing your repo as a custom element, so when you are importing the #master.js it is looking for the matching "view" of what it assumes is a viewmodel.
It sounds like you need to structure your repository as a plugin. Add an index.js file at the top level and make that responsible for running the configure function, which should make the components you want global resources. Ensure your package.json points to your index.js as the 'main'. After that, you would need to add a .plugin('your-package-name') in the main.js file, just like any other plugin.
An example index.js is like so:
import {Options, GLOBAL_OPTIONS, DIRECTION} from './options';
import {Dragula} from './dragula';
import {moveBefore} from './move-before';
export {Dragula, Options, DIRECTION, moveBefore};
export function configure(config, callback) {
let defaults = new Options();
config.container.registerInstance(GLOBAL_OPTIONS, defaults);
if (callback !== undefined && typeof callback === 'function') {
callback(defaults);
}
config.globalResources(['./dragula-and-drop']);
}
(taken from here)