i am using fastify with point-of-view module to render pug templates:
Fastify.register(require('point-of-view'), {
engine: {
pug: require('pug')
},
templates: Path.join(__dirname,'templates'),
options: {
filename: Path.join(__dirname,'templates/layout.pug'),
globals: [
{
assets_path: 'Path_to_assets'
}
]
}
})
how I can access to globals inside pug templates?
well, I found a method: accessing to env vars.
in my templates I use
global.process.env.ASSETS_PATH
where ASSETS_PATH is declared as part of my env vars
You can't access 'options' parameter. But you can pass your variable via defaultContext like this:
fastify.register(require('point-of-view'), {
engine: {
pug: require('pug')
},
defaultContext: {
// Place your variable here
globals: [],
myVars,
appName: 'Fastify Website'
},
templates: Path.join(__dirname,'templates'),
options: {
filename: Path.join(__dirname,'templates/layout.pug'),
globals: [
{
assets_path: 'Path_to_assets'
}
]
}
})
Related
I'm building a chrome extension using Vite as my build tool. The main problem is during minification and mangling there are a lot of global variables created. After injecting my script to the page they conflict with already defined variables on window object.
I imagine the perfect solution would be to have my entire script wrapped in IIFE. I tried using esbuild.format = 'iife'. The resulting build is in fact wrapped in IIFE, however all the imports are not inlined. Instead resulting script is like 15 lines long with a bunch of require statements, which obviously does not work in the browser.
This is my config file:
export default defineConfig({
plugins: [
vue(),
],
esbuild: {
format: 'iife',
},
build: {
emptyOutDir: false,
rollupOptions: {
input: resolve(__dirname, './src/web/index.ts'),
output: {
dir: resolve(__dirname, './dist'),
entryFileNames: 'web.js',
assetFileNames: 'style.css',
},
},
},
resolve: {
alias: {
'#': resolve(__dirname, './src'),
},
},
});
I'm currently using this hack so to say to wrap my build in IIFE (for this I removed the esbuild.format option).
Hey I am doing the exact same thing! And I also noticed the unminified variables and functions can clash with random code in a webpage.
From what I researched myself on this topic, you shouldn't change esbuild build options with Vite as that will prevent Rollup from transforming the output. Instead, you should use format: 'iife' in the rollupOptions of your vite.config. However, in my case (and yours I believe), I have to output multiple bundles since the extension code can't share modules amongst each other. Which will crash when you set the format to 'iife' due to:
Invalid value for option "output.inlineDynamicImports" - multiple inputs are not supported when "output.inlineDynamicImports" is true.
The only solution in my case seems to be to either use multiple vite.configs (I already have two) for each of my bundle with single input entry point and format as 'iife'. Or, as you did, just write the self-invoking function yourself with some hacky script. Seems though there aren't any perfect solutions as of now.
EDIT: Okay, got it working. This is my vite.config.ts (the project):
import { defineConfig } from 'vite'
import { svelte } from '#sveltejs/vite-plugin-svelte'
import tsconfigPaths from 'vite-tsconfig-paths'
import path from 'path'
/** #type {import('vite').UserConfig} */
export default defineConfig({
plugins: [svelte({}), tsconfigPaths()],
build: {
minify: false,
rollupOptions: {
output: {
chunkFileNames: '[name].js',
entryFileNames: '[name].js'
},
input: {
inject: path.resolve('./src/inject.ts'),
proxy: path.resolve('./src/proxy.ts'),
'pop-up': path.resolve('./pop-up.html')
},
plugins: [
{
name: 'wrap-in-iife',
generateBundle(outputOptions, bundle) {
Object.keys(bundle).forEach((fileName) => {
const file = bundle[fileName]
if (fileName.slice(-3) === '.js' && 'code' in file) {
file.code = `(() => {\n${file.code}})()`
}
})
}
}
]
}
}
})
Okay, I made it working with this config:
export default defineConfig({
plugins: [
vue(),
],
build: {
emptyOutDir: false,
rollupOptions: {
input: resolve(__dirname, './src/web/index.ts'),
output: {
format: 'iife',
dir: resolve(__dirname, './dist'),
entryFileNames: 'web.js',
assetFileNames: 'style.css',
},
},
},
resolve: {
alias: {
'#': resolve(__dirname, './src'),
},
},
});
They key part is format: 'iife' inside build.rollupOptions.output.
I have an app folder with some images that are used by the external script and I need to include those images in the dist build folder.
I tried to log files that go to output and those images are not included. I tried to add assetsInclude property but seems that property is not for that purpose.
How can I include some specific images in dist folder that aren't imported explicitly ?
Here is my vite.config.js file.
import { resolve, parse } from 'path';
import { defineConfig } from 'vite';
export default defineConfig({
base: '/',
root: resolve(__dirname, 'app'),
assetsInclude: ['/app/images/externalImage.png'],
build: {
emptyOutDir: true,
rollupOptions: {
output: {
dir: './dist',
assetFileNames: (asset) => {
console.log(parse(asset.name).name);
if (parse(asset.name).name === 'externalImage') {
return "images/src/[name][extname]";
}
return "assets/[name].[hash][extname]";
}
},
},
},
});
In my js file which is included as a module inside the HTML file, I added string that you can see below. Here is details of how to expose the current module URL.
app/js/app.js
new URL("../images/src/externalImage.png", import.meta.url);
Also changed a bit config - added outDir prop:
import { resolve, parse } from 'path';
import { defineConfig } from 'vite';
export default defineConfig({
base: '/',
root: resolve(__dirname, 'app'),
build: {
outDir: '../dist',
emptyOutDir: true,
rollupOptions: {
output: {
assetFileNames: (asset) => {
if (parse(asset.name).name === 'externalImage') {
return "images/src/[name][extname]";
}
return "assets/[name].[hash][extname]";
}
},
},
},
});
How can I use the prometheus within a LoopBack 4 application
here is a piece of code from the application.ts file
export class BackendV4Application extends BootMixin(ServiceMixin(RepositoryMixin(RestApplication))) {
constructor(options?: ApplicationConfig)
{
options = { ...options, rest: { requestBodyParser: { json: { limit: '6mb' } } } };
super(options);
// Set up dotenv
dotenv.config();
// Set up the base path
this.basePath('/api');
this.api({
openapi: '3.0.0',
info: { title: pkg.name, version: pkg.version },
paths: {},
components: { securitySchemes: SECURITY_SCHEME_SPEC },
servers: [{ url: '/api' }]
});
this.setUpBindings();
There's a component package #loopback/metrics made by LoopBack that implements Prometheus. The Metrics collection for Prometheus documentation page explains how to set it up in the application.
I'm using Yeoman template to develop a static web site. grunt serve nicely works with the auto reload plugin.
For repeating elements I started to use {{mustache}} partials and it works like a blast. Now I want the auto reload to assemble my page, so I can look at the resulting page when editing one of the mustache files (either a main file or a partial).
I found a grunt task for it, but stitching it together eludes me. My config looks like this:
grunt.initConfig({
sass: {
dev: {
src: ['src/sass/*.sass'],
dest: 'dest/css/index.css',
},
},
watch: {
sass: {
// We watch and compile sass files as normal but don't live reload here
files: ['src/sass/*.sass'],
tasks: ['sass']
},
mustache: {
files: '**/*.mustache',
tasks: ['mustache_render'],
options: {
interrupt: true
},
},
livereload: {
options: { livereload: true },
files: ['dest/**/*']
}
},
mustache_render: {
options: {
{data: 'common-data.json'}
},
your_target: {
files: [
{expand: true,
template: '**/*.mustache',
dest: 'dest/'}
]
}
}
});
I must be missing something since the html files are not updated when I save the file.
You can add the livereload option directly to your mustache target options.
grunt.initConfig({
watch: {
mustache: {
files: '**/*.mustache',
tasks: ['mustache_render'],
options: {
interrupt: true,
livereload: true
},
}
},
mustache_render: {
options: {
{data: 'common-data.json'}
},
main: {
files: [
{expand: true,
template: '**/*.mustache',
dest: 'dest/'}
]
}
}
});
Also, if you're using grunt-contrib-connect to serve your files, don't forget to add the livereload option to it:
connect: {
http: {
options: {
hostname: "*",
port: process.env.PORT || 80,
livereload: true
}
}
}
My precompiled template file is templates.js -- how do I load this file using RequireJS?
requirejs.config({
paths: {
jquery: '../bower_components/jquery/jquery'
, underscore: '../bower_components/underscore/underscore'
, handlebars: '../bower_components/handlebars/handlebars'
, moment: '../bower_components/momentjs/moment'
, spin: '../bower_components/spinjs/spin'
, templates: 'templates'
},
shim: {
handlebars: {
exports: 'Handlebars'
},
templates: {
deps: ['handlebars']
}
}
});
requirejs(["jquery", "underscore", "handlebars", "templates", "moment", "spin", "test"], function($, _, Handlebars, Templates, moment, Spinner, test) {
test.init();
});
You should compile your templates with AMD support . ( I usually do it with help of this Grunt plugin .)
requirejs.config({
paths: {
jquery: '../bower_components/jquery/jquery'
, underscore: '../bower_components/underscore/underscore'
, handlebars: '../bower_components/handlebars/handlebars'
, moment: '../bower_components/momentjs/moment'
, spin: '../bower_components/spinjs/spin'
, templates: 'templates'
},
shim: {
handlebars: {
exports: 'Handlebars'
}
}
});
requirejs(["jquery", "underscore", "templates", "moment", "spin", "test"]
, function($, _, Templates, moment, Spinner, test) {
test.init();
});
Now Templates is an object whose keys are the names of the templates and whose values are the Handlebars templating functions .
Usage example :
var template = Templates['templates/posts.hbs'];
document.body.innerHTML = template({
title: 'All posts',
posts: [
{ title: 'First post', '13/11/2013'},
{ title: 'Second post', '15/11/2013'}
]
});