Bundle Handsontable into Aurelia application - javascript

I'd like to know how to correctly bundle handsontable community edition library into Aurelia application. Handsontable is distributed as single JS file packed as webpack module, thus a hint may be useful for webpack modules generally.
Having Aurelia version 0.24.0 configured with default loader: RequireJS and default transpiler: Babel, NPM version 3.10.0. I did following steps in order to bundle handsontable into my application:
npm install handsontable
then edited aurelia-project/aurelia.json to add the following
dependencies:{ ...
{
"name": "handsontable",
"path": "../node_modules/handsontable",
"main": "dist/handsontable.full",
"resources": [
"dist/handsontable.full.css"
]
},
Then the component looks like: (view - htable.html):
<template>
<div ref="filetable"></div>
</template>
(viewmodel - htable.js in ES6):
import {Handsontable} from "handsontable";
export class htable {
...
attached() {
this.ht = new Handsontable (this.filetable, {
data: this.data,
rowHeaders: true,
colHeaders: true
});
}
}
However, any attempt to add such component fails with
Unhandled rejection TypeError: _handsontable is undefined
Another attemp I use in different library produce similar error:
import * as Handsontable from "handsontable";
...
this.ht = new Handsontable.Handsontable (this.filetable, {
Btw. A workaround is not to bundle and add handsontable into index.html which makes "Handsontable" global.

Related

Openlayers in nuxt blob is undefined

I'm trying to make openlayers work in Nuxt but whenever I tried to import openlayers components, I had several errors that I solved, but one of them is "Blob is not defined - node_modules/ol/worker/webgl.js"
I found nothing on openlayers and nuxt and i'm having hard times to just make it work :/
Here is the steps of what I did :
npm install ol
made a file with import View from 'ol/View', got error "can't import ESM module...."
created a plugins folder with a ol.js with all OL assests imported, and added plugins: ['#/plugins/ol'] in nuxt.config
preview of my ol.js file in my plugins folder
Got error "can't read fs" file
added extend: (config, { isDev, isClient }) => { config.node = {fs: 'empty',} into my nuxt.config file in build
Also added standalone: true,
and NOW I have blob is undefined and really, I have no clue on what to do to make openlayers work :/
Any help is welcome !
EDIT : Made some changes
1 I installed vuelayers
2 followed the guide on https://vuelayers.github.io/#/docs/quickstart?id=nuxtjs
edited nuxt.config
plugins: [{
src: '#/plugins/vuelayers.js',
ssr: false
}, { ... }],
modules: [
...,
'~/shared/vueLayers',
],
Create a file shared/ directory named vuelayers.js
export default function (moduleOptions) {
this.options.css.push('vuelayers/lib/style.css')
}
3 pasted the content of the "simple map example"
I have no error but nothing is displayed on my component yet
The "can't import ESM module...." occurs because the ol package exports an ES6 module and when Nuxt is rendered on the server side the parent project uses CommonJS modules. As a result a run time error occurs when the open layers code is not transpiled for server side rendering.
I found there to be two solutions to this problem.
Explicitly transpile the Open Layers modules that are used in the transpile property of the build property in nuxt.config.js
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
transpile: [
'ol/control',
'ol/proj',
'ol/style/Circle',
'ol/style/Fill',
'ol/format/GeoJSON',
'ol/format/MVT',
'ol/Map',
// ...
],
},
Create a Nuxt plug-in to wrap Open Layers that's only used on the client side similar to the example seen in this gist.
I found the second solution to be cleaner and since Open Layers uses <canvas> render the map it can't easily be rendered on the server side anyway.
Note that the Gist linked above is a bit dated, but the idea is still relevant. A modern example might look like the following:
// plugins/open-layers.js
import Map from 'ol/Map';
import View from 'ol/View';
export default (context, inject) => {
const ol = {
Map,
View,
};
inject('ol', ol);
};
// nuxt.config.js
export default {
// ...
plugins: [
{ src: '~/plugins/open-layers.js', mode: 'client' },
],
};
// Parent component
<template>
<client-only>
<Map />
</client-only>
</template>
// Map.vue
<template>
<div ref="map" />
</template>
<script>
export default {
name: 'Map',
methods: {
renderChart() {
this.map = new $ol.Map({
target: this.$refs.map,
view: new $ol.View({}),
});
},
},
};
</script>

Global styles for StencilJs custom web component not recognized in Angular app

I've used Stencil to create a custom web component.
I've set a bunch of CSS variables in /src/global/global.scss:
E.g.:
:root {
--font-family: 'Roboto Condensed';
--font-size: 1.75rem;
... etc ...
}
My stencil.config.ts looks like this:
export const config: Config = {
namespace: 'my-component',
globalStyle: 'src/global/global.scss',
outputTargets: [
{
type: 'dist',
esmLoaderPath: '../loader',
},
{
type: 'dist-custom-elements-bundle',
}
],
};
If I publish the component to NPM, then install it into my Angular app, it works, except that it doesn't recognize any of the variables defined in the global CSS file.
In my Angular project - the file is here, and does contain the variables:
/node_modules/my-component/dist/my-component/my-component.css
It's just that my Angular project doesn't seem to be aware of that file.
I've read elsewhere that I should include this line in the index.html file of my Angular project:
<link rel="stylesheet" href="/dist/my-component/my-component.css">
However, I've tried that, by when I run ng serve, the browser doesn't find:
http://localhost:4200/dist/my-component/my-component.css
I'm guessing that I'm missing some configuration setting that tells Angular to copy the CSS file from /node_modules/my-component/dist/my-component/my-component.css to dist/my-component/my-component.css, but I don't know how or where to do that.
in angular.json:
"styles": [
"./node_modules/my-component/dist/my-component/my-component.css",
"src/styles.scss"
],

Tailwind and storybook setup postcss config issue

I have the following postccs.config.js file:
module.exports = {
plugins: [
require("postcss-import"),
require("tailwindcss"),
require("autoprefixer"),
],
}
which allows me to run tailwind and storybook together, however when I try to run my application, I get this error:
Error: A PostCSS Plugin was passed as a function using require(), but it must be provided as a string.
Is there a way to provide a specific storybook postcss config or even a better way for the 2 to work with the same config?
you need to execute the require.
Your config should look like this:
module.exports = {
plugins: [
require('postcss-import')(),
require('tailwindcss')('./tailwind.config.js'), //This refers to your tailwind config
require('autoprefixer'),
],
};
also this was answered before #see: How to configure VueJS + PostCss + Tailwind with Storybook

What causes failure to compile SASS in this svelte applcation?

I am working on a project with Svelte and the material design library Svelte Material UI.
This material design library requires SASS, so I installed a preprocessor with npm install svelte-preprocess and added preprocess: autoPreprocess() in rollup.config.js. So I now have:
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('public/build/bundle.css');
},
preprocess: autoPreprocess()
}),
routify({ singleBuild : true}),
replace({
// stringify the object
APPENV: JSON.stringify({
isProd: production,
...config().parsed // attached the .env config
}),
}),
// more stuff
]
I have a file smui.js with this content:
import Button from '#smui/button';
import Checkbox from '#smui/checkbox';
import Chips from '#smui/chips';
import Dialog from '#smui/dialog';
import FormField from '#smui/form-field';
import Select from '#smui/select';
export {
Button,
Checkbox,
Chips,
Dialog,
FormField,
Select
}
In my index.svelte file I am importing the above this way: import * as Smui from "../smui.js";.
Instead of a success message with the port on which the app should run, I get:
[!] Error: Unexpected character '#' (Note that you need plugins to import files that are not JavaScript)
node_modules\#smui\dialog\_index.scss (1:0)
1: #import "smui-theme";
^
2: #import "./style";
Error: Unexpected character '#' (Note that you need plugins to import files that are not JavaScript)
What am I doing wrong?
I had the same issue and somehow I managed to fix this with rollup-plugin-postcss plugin. Update your rollup.config.js with the following code and you should have _smui-theme.scss in your one of sass directories.
import postcss from 'rollup-plugin-postcss'
...
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('public/build/bundle.css')
}
}),
postcss({
extensions: ['.css'],
extract: true,
minimize: true,
use: [['sass', { includePaths: ['./src/(yoursass-directory-name)', './node_modules'] }]]
})
I've never used #import to import components from a NPM package, but at the readme package you're referencing it recommends using 'import x from" svelte-material'. Also pay attention that svelte-preprocess won't be supported by the package you're referencing, take a look at the readme:
To bundle this in your own code, use a Sass processor (not a Sass Svelte preprocessor, but a Sass processor).

How Should VSCode Be Configured To Support A Lerna Monorepo?

I have a lerna monorepo containing lots of packages.
I'm trying to achieve the following:
Ensure that VSCode provides the correct import suggestions (based on package names, not on relative paths) from one package to another.
Ensure that I can 'Open Definition' of one of these imports and be taken to the src of that file.
For 1. I mean that if I am navigating code within package-a and I start to type a function exported by package-b, I get a suggestion that will trigger the adding of an import: `import { example } from 'package-b'.
For 2. I mean that if I alt/click on the name of a function exported by 'package-b' while navigating the file from a different package that has imported it, I am taken to '/packages/namespace/package/b/src/file-that-contains-function.js',
My (lerna) monorepo is structured as standard, for example here is a 'components' package that is published as #namespace/components.
- packages
- components
- package.json
- node_modules
- src
- index.js
- components
- Button
- index.js
- Button.js
- es
- index.js
- components
- Button
- index.js
- Button.js
Note that each component is represented by a directory so that it can contain other components if necessary. In this example, packages/components/index exports Button as a named export. Files are transpiled to the package's /es/ directory.
By default, VSCode provides autosuggestions for imports, but it is confused by this structure and, for if a different package in the monorepo needs to use Button for example, will autosuggest all of the following import paths:
packages/components/src/index.js
packages/components/src/Button/index.js
packages/components/src/Button/Button.js
packages/components/es/index.js
packages/components/es/Button/index.js
packages/components/es/Button/Button.js
However none of these are the appropriate, because they will be rendered as relative paths from the importing file to the imported file. In this case, the following import is the correct import:
import { Button } from '#namespace/components'
Adding excludes to the project's jsconfig.json has no effect on the suggested paths, and doesn't even remove the suggestions at /es/*:
{
"compilerOptions": {
"target": "es6",
},
"exclude": [
"**/dist/*",
"**/coverage/*",
"**/lib/*",
"**/public/*",
"**/es/*"
]
}
Explicitly adding paths using the "compilerOptions" also fails to set up the correct relationship between the files:
{
"compilerOptions": {
"target": "es6",
"baseUrl": ".",
"paths": {
"#namespace/components/*": [
"./packages/namespace-components/src/*.js"
]
}
},
}
At present Cmd/Clicking on an import from a different package fails to open anything (no definition is found).
How should I configure VSCode so that:
VSCode autosuggests imports from other packages in the monorepo using the namespaced package as the import value.
Using 'Open Definition' takes me to the src of that file.
As requested, I have a single babel config in the root:
const { extendBabelConfig } = require(`./packages/example/src`)
const config = extendBabelConfig({
// Allow local .babelrc.js files to be loaded first as overrides
babelrcRoots: [`packages/*`],
})
module.exports = config
Which extends:
const presets = [
[
`#babel/preset-env`,
{
loose: true,
modules: false,
useBuiltIns: `entry`,
shippedProposals: true,
targets: {
browsers: [`>0.25%`, `not dead`],
},
},
],
[
`#babel/preset-react`,
{
useBuiltIns: true,
modules: false,
pragma: `React.createElement`,
},
],
]
const plugins = [
`#babel/plugin-transform-object-assign`,
[
`babel-plugin-styled-components`,
{
displayName: true,
},
],
[
`#babel/plugin-proposal-class-properties`,
{
loose: true,
},
],
`#babel/plugin-syntax-dynamic-import`,
[
`#babel/plugin-transform-runtime`,
{
helpers: true,
regenerator: true,
},
],
]
// By default we build without transpiling modules so that Webpack can perform
// tree shaking. However Jest cannot handle ES6 imports becuase it runs on
// babel, so we need to transpile imports when running with jest.
if (process.env.UNDER_TEST === `1`) {
// eslint-disable-next-line no-console
console.log(`Running under test, so transpiling imports`)
plugins.push(`#babel/plugin-transform-modules-commonjs`)
}
const config = {
presets,
plugins,
}
module.exports = config
In your case, I would make use of lerna in combination with yarn workspaces.
When running yarn install, all your packages are linked under your #namespace in a global node_modules folder. With that, you get IntelliSense.
I've set up an example repository here: https://github.com/flolude/stackoverflow-lerna-monorepo-vscode-intellisense
You just need to add "useWorkspaces": "true" to your lerna.json
lerna.json
{
"packages": ["packages/*"],
"version": "0.0.0",
"useWorkspaces": "true"
}
And the rest is just propper naming:
global package.json
{
"name": "namespace",
// ...
}
package.json of your component package
{
"name": "#namespace/components",
"main": "src/index.js",
// ...
}
package.json of the package that imports the components
{
"name": "#namespace/components",
"main": "src/index.js",
"dependencies": {
"#namespace/components":"0.0.0"
}
// ...
}
Then you can do the following:
import { Component1 } from '#namespace/components';
// your logic
Automatically Importing from #namespace
Unfortunately, I couldn't find a way to make this work in VSCode with a Javascript Monorepo. But there are some things you can do:
Use Typescript (tutorial, other tutorial)
Use module-alias
Add import {} from '#namespace/components' to the top of your file
Use Auto Import Extension
Edit: This is broken with the latest version of VSCode.
I finally managed to get this working reliably. You need to create a separate jsconfig.js for every package in your monorepo, for example:
{monorepo root}/packages/some-package/jsconfig.json:
{
"compilerOptions": {
"target": "es6",
"jsx": "preserve",
"module": "commonjs"
},
"include": ["src/**/*.js"],
"exclude": ["src/index.js"]
}
Note that I've excluded the src/index.js file so it doesn't get offered as an import suggestion from within that package.
This setup appears to achieve:
Intellisense import suggestions from packages instead of using relative paths.
Go to definition to source of other packages in the monorepo.
VSCode has been pretty flaky of late, but it seems to be working.
Note this is working for a JavaScript-only monorepo (not Typescript).

Categories

Resources