How to use import Leaflet in Sails.js? - npm

Super basic question: I want to install and use the Leaflet module in my Sails.js project. First thing, I install it in using npm i leaflet --save. This successfully updates the dependencies list in the package.json file.
To use it, I write the following code inside a page script:
mounted: async function() {
//…
console.log('hello world!!!!');
var leaflet = require("leaflet");
},
Sails.js complains: Uncaught (in promise) ReferenceError: require is not defined.
Why? If I need to create a hook first, what would it need to contain?

Modules installed through the package manager npm are to be used in the server-side of things (controllers, actions, etc.), not in the browser.
You could use solutions such as Browserify or Webpack, but in this case it's just better to download Leaflet from the website and add the folder under assets/dependencies.
Finally, you can import the JavaScript Leaflet files in layout.ejs (inside the views/layouts folder):
<% /* Auto-injected «script» tags: */ %>
<!--SCRIPTS-->
// ...
<script src="/dependencies/leaflet/leaflet.css"></script>
And for CSS:
<% /* Auto-injected «link» tags: */ %>
<!--STYLES-->
// ...
<link rel="stylesheet" href="/dependencies/leaflet/leaflet.css">
I would guess this is the best approach as the Sails.js starter template is importing Boostrap 4 in the same way.

You don't have to require anything, once you npm installed it just add the leaflet.js, leaflet.markercluster.js and leaflet.css in your header and you're done.
You can use the short example of init map from their site and it'll work.

Related

How to bundle tailwind css inside a Vue Component Package

In one of my projects, I build a nice vue3 component that could be useful to several other projects. So I decided to publish it as an NPM package and share it with everyone.
I wrote the isolate component, build it and publish BUT I use Tailwind css to make the style.
When I publish and install the component everything is working BUT without the beauty of the css part.
I tried several configurations and alternative tools to generate the package that automatically add the tailwind as an inner dependency to my package.
Does someone have experience with this? how can build/bundle my component by adding the tailwind CSS instructions into it?
You're almost there
Since you've got your component working, the majority of the part has been done.
For configuring the styling of the component you need to identify the Tailwind CSS classes being used by your Vue component package and retain them in the final CSS that is generated by the Tailwind engine in your project.
Follow below steps in the project where you want to use your tailwind vue component package.
For Tailwind CSS V3
// tailwind.config.js
module.exports = [
//...
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}",
"./node_modules/package-name/**/*.{vue,js,ts,jsx,tsx}" // Add this line
// Replace "package-name" with the name of the dependency package
],
//...
]
For Tailwind CSS V2
// tailwind.config.js
module.exports = [
//...
purge: {
//...
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}",
"./node_modules/package-name/**/*.{vue,js,ts,jsx,tsx}" // Add this line
// Replace "package-name" with the name of the dependency package
],
//...
//...
}
]
The content property in the tailwind.config.js file defines file path pattern that the tailwind engine should look into, for generating the final CSS file.
For Pro users
You may also try to automate the above setup by writing an install script for your npm package to add this configuration to the tailwind.config.js file
References
Tailwind Docs - 3rd party integration
It's a bit difficult for someone to answer your question as you've not really shared the source code, but thankfully (and a bit incorrectly), you've published the src directory to npm.
The core issue here is that when you're building a component library, you are running npm run build:npm which translates to vue-cli-service build --target lib --name getjvNumPad src/index.js.
The index.js reads as follows:
import component from './components/numeric-pad.vue'
// Declare install function executed by Vue.use()
export function install (Vue) {
if (install.installed) return
install.installed = true
Vue.component('getjv-num-pad', component)
}
// Create module definition for Vue.use()
const plugin = {
install
}
// Auto-install when vue is found (eg. in browser via <script> tag)
let GlobalVue = null
if (typeof window !== 'undefined') {
GlobalVue = window.Vue
} else if (typeof global !== 'undefined') {
GlobalVue = global.Vue
}
if (GlobalVue) {
GlobalVue.use(plugin)
}
// To allow use as module (npm/webpack/etc.) export component
export default component
There is no mention of importing any CSS, hence no CSS included in the built version.
The simplest solution would be to include the index.css import in your index.js or the src/components/numeric-pad.vue file under the <style> section.
Lastly, I'm a bit rusty on how components are built, but you might find that Vue outputs the CSS as a separate file. In that case, you would also need to update your package.json to include an exports field.

Vue: icons are not displayed when css.extract: false

When building a Vue library (component), according to Vue docs, you can set css.extract: false in vue.config.js to avoid the users having to import the CSS manually when they import the library into an app:
vue.config.js
module.exports = {
css: {
extract: false
}
}
However, when you do that, the icons are not displayed in the production build.
In this case I'm using #mdi/font and weather-icons. Neither of them load:
To reproduce
You can reproduce this with this Vue library (component):
Create new Vue project with vue create test
Clone the repo and put in the same directory as the Vue test project
In vue-open-weather-widget set css.extract: false in vue.config.js;
And comment out CSS import:
import 'vue-open-weather-widget/dist/vue-open-weather-widget.css'
Build vue-open-weather-widget with yarn build
Import it into the test Vue app with yarn add "../vue-open-weather-widget";
Serve the test app yarn serve
I have looked at your lib (nice component BTW). I created a build with css: { extract: false } and first looked at the behavior when importing vue-open-weather-widget.umd.js directly into an HTML file. And that worked without any problems.
The thing is that the fonts remain external in the dist after the build. And it seems that there is a problem to find the fonts when your component is loaded in a Webpack project (in our case Vue CLI project). I don't know why the fonts are not referenced correctly. But I have found another, and possibly a better solution.
As it is stated in the MDI docs, the use of the web fonts can negatively affect the page performance. When importing only one icon, all of them are imported, which in turn increases the bundle size. In such a small component this is more than suboptimal, especially for the component users. Therefore here is the alternative solution, also suggested by MDI:
Use #mdi/js instead of #mdi/font
Remove all #mdi/font references in your code and install deps:
npm install #mdi/js #jamescoyle/vue-icon
Replace all icons with SVG(e.g. in MainView.vue). Note that on this way only icons are included in the bundle that are used in your components:
...
<span #click="state.settings.view = 'settings'">
<svg-icon type="mdi" :path="mdiCogOutline"></svg-icon>
</span>
...
import SvgIcon from '#jamescoyle/vue-icon'
import { mdiCogOutline } from '#mdi/js'
...
components: {
SvgIcon
},
data () {
return {
mdiCogOutline: mdiCogOutline
}
},
Adjust vue.config.js:
module.exports = {
css: {
extract: false
}
}
Build component:
# i would also include --formats umd-min
vue-cli-service build --target lib --formats umd-min --name vue-open-weather-widget src/main.js
Now your dist contains only 192.68 KiB vue-open-weather-widget.umd.min.js and the component is ready to use over CDN or in a Vue CLI Project, without importing any CSS or fonts. I have tested both cases. Here is how it looks like:
Hope it helps you! Feel free to ask if you have further questions.

Vue "These relative modules were not found" when using scss file

I'm trying to use a Bootstrap theme in my Vue application. Unfortunately the Bootstrap theme has no reference implementation for Vue. So I need to configure everything on my own.
What I want to do is, I want use the scss-files provided by the theme in Vue. So my App.vue component is pretty simple:
<template>
<div id="app">
</div>
</template>
<style lang="scss">
#import "#/assets/base.scss";
</style>
The "base.scss" file contains imports all dependencies. So, when I run my Vue application using "npm run serve", I get the following error:
ERROR Failed to compile with 10 errors
This dependency was not found:
-!../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!typicons.font/src/font/typicons.css
in ./node_modules/cs
s-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist /cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=1&lang=scss&
To install it, you can run: npm install --save
-!../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!typicons.fo
nt/src/font/typicons.css
These relative modules were not found:
./components/icons/linearicons/Linearicons-Free.eot in ./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_modules/
sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=1&lang=scss&
./components/icons/linearicons/Linearicons-Free.eot?w118d in ./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_mo
dules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=1&lang=scss&
./components/icons/linearicons/Linearicons-Free.svg?w118d in ./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_mo
dules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=1&lang=scss&
./components/icons/linearicons/Linearicons-Free.ttf?w118d in ./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_mo
dules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=1&lang=scss&
./components/icons/linearicons/Linearicons-Free.woff2?w118d in ./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_
modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=1&lang=scss&
./components/icons/linearicons/Linearicons-Free.woff?w118d in ./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_m
odules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=1&lang=scss&
./components/slick-carousel/slick/ajax-loader.gif in ./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_modules/sa
ss-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=1&lang=scss&
./utils/images/logo-inverse.png in ./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_modules/sass-loader/dist/cjs
.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=1&lang=scss&
./utils/images/logo.png in ./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_modules/sass-loader/dist/cjs.js??ref
--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=1&lang=scss&
Error from chokidar (C:): Error: EBUSY: resource busy or locked,
lstat 'C:\hiberfil.sys'
The referenced files are exist in the "#/assets/components/..." directory. But my problem is that I've no idea how I can set a relative path (e.g. "#/assets") searchs for the components. Furthermore there's no variable in the "base.scss" file I can adjust to set the relativ path. I also don't want modify the "base.scss" file because it comes from the theme.
I've no idea how to fix it this. I already tried to set the corresponding webpack-chain in vue.config.js without any success:
module.exports = {
chainWebpack: config => {
config.module
.rule('fonts')
.test(/\.(ttf|otf|eot|woff|woff2)$/)
.use('file-loader')
.loader('file-loader')
.tap(options => {
options = {
name: '#/assets/[path][name].[ext]'
}
return options
})
.end()
}
I hope anyone can help solving this problem :-)
I finally solved the issue by simply importing the "base.scss" in the "main.js" file and use it:
import theme from '#/assets/base.scss'
Vue.use(theme)

Generate PDF file from html using angular2/typescript

I want to take a part of my HTML template and convert it to PDF file to give the user an option to download it. (After they click a button for example).
I found a library called jsPDF, how would I use jsPDF in an Angular2 app (RC4)?
thank you
If you want to use it in production, you definitely don't want to depend on an internet link being referenced in your index.html, like proposed by #khalil_diouri.
So, to properly use it in an Angular2/Typescript environment,
first install it from npm
npm install --save jspdf
If you are using SystemJS, map it in your config file
map: {
"jspdf": "node_modules/jspdf/dist/jspdf.min.js"
}
Install definition package: (if not installed)
npm install typings --global
Install definition files:
typings install dt~jspdf --global --save
And, finally, import it in your component.ts file
import jsPDF from 'jspdf'
...
let doc = new jsPDF();
doc.text(20,20,'Hello world');
doc.save('Test.pdf');
...
as a response
this link is necessary to import jsPDF content
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.0.272/jspdf.debug.js"></script> // to use jsPDF for registring pdf file
then in you component.ts
you do that
declare let jsPDF;
#Component({
template: `
<button
(click)="download()">download
</button>
`
})
export class DocSection {
constructor() {
}
public download() {
var doc = new jsPDF();
doc.text(20, 20, 'Hello world!');
doc.text(20, 30, 'This is client-side Javascript, pumping out a PDF.');
doc.addPage();
doc.text(20, 20, 'Do you like that?');
// Save the PDF
doc.save('Test.pdf');
}
}
the AddHtml method is deprecated :
Source:
plugins/addhtml.js, line 12
Deprecated:
This is being replace with a vector-supporting API. see here
Renders an HTML element to canvas object which added to the PDF
This feature requires html2canvas or rasterizeHTML
Why use Definition (also known as Declaration) files?
To use external javascript libraries (jsPDF, for example) with Angular2 applications (which use Typescript) you are going to want Type Definition files for those javascript libraries. These files provide type information (as in String, Number, boolean, etc.) to typescript for help with compile time type checking. (Since javascript is loosely typed)
Another explanation about d.ts files can be found here.
How to use
You can download an npm package called typings which will help expedite the process. Here's a short guide on how to use it. Once you have typings installed, you can run:
npm run -- typings install dt~jspdf --global --save
to get the typings file which you can then use in your project.

JSPM / Aurelia / Bootstrap 4 can't find jQuery

So I have an aurelia setup using jspm. I have install Bootstrap 4 like so:
jspm install npm:bootstrap#4.0.0-alpha.2
Then in main.js I did:
import 'jquery';
import 'bootstrap';
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging();
//Uncomment the line below to enable animation.
//aurelia.use.plugin('aurelia-animator-css');
//if the css animator is enabled, add swap-order="after" to all router-view elements
//Anyone wanting to use HTMLImports to load views, will need to install the following plugin.
//aurelia.use.plugin('aurelia-html-import-template-loader')
aurelia.start().then(() => aurelia.setRoot());
}
I even tried import $ from 'jquery' but when I spin up the aurelia skeleton with BS4 I get:
Uncaught Error: Bootstrap's JavaScript requires jQuery
I can go to the console and do $ and it returns the jquery stuff. I think it is a race condition but not sure how to fix?
EDIT: System.config
System.config({
defaultJSExtensions: true,
transpiler: "none",
paths: {
"*": "dist/*",
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*"
},
meta: {
"bootstrap": {
"deps": [
"jquery"
]
}
},
map: {
Use jspm install bootstrap=github:twbs/bootstrap#4.0.0-alpha.2
There are problems installing bootstrap with jspm from npm: (see here).
See this file for how to import it (from this project).
Update: here is the Pull Request that should fix this.
I ran into this issue recently as well. Try installing jquery 2, instead of jquery 3. Apparently jquery 3 doesn't hang itself off window when it's imported as a module the same as it does in jquery 2. Bootstrap 4 doesn't apparently doesn't request it as a dependency either.
One possible solution is to load jQuery from a CDN in the HEAD section of your index.html:
<script src="https://code.jquery.com/jquery-3.0.0.min.js" integrity="sha256-JmvOoLtYsmqlsWxa7mDSLMwa6dZ9rrIdtrrVYRnDRH0=" crossorigin="anonymous"></script>
Taken from https://code.jquery.com. Use a different version of jQuery if you need. This is actually a better deployment strategy IMHO anyway because you will get more concurrent downloads (better parallelism) in the browser by loading libraries from CDNs.