Stencil - Global CSS Doesn't Integrate into React - javascript

Following the Stencil docs here, I created some global CSS variables in src/global/variables.css. This is currently the only CSS file in this directory.
I’m trying to use my component(s) in React. The components / CSS variables work perfectly fine when developing in the Stencil project and when I copy the www/build/ directory to a vanilla JS / HTML project but not when I import and use them in React. The components work and clearly render but the CSS in the global/ directory clearly doesn’t get rendered.
Defining and using CSS variables within the component CSS files works, but not the global CSS files.
I’m guessing something is wrong with how I’m building it but I don’t know what I’m doing wrong.
I've tried updating to the most recent Stencil version and updated all other packages.
I've also tried adding:
styleUrls: [
"local-component.css",
"../../global/variables.css"
]
but this also did not work.
It only works if add a CSS tag referencing the UNPKG CDN like so:
<link rel="stylesheet" type="text/css" href="https://unpkg.com/uwe-ds-poc#0.0.9/dist/poc/poc.css"/>
but fails if I try to do a local path like this:
<link rel="stylesheet" type="text/css" href="../node_modules/uwe-ds-poc/dist/poc/poc.css"/>.
Is this the only / best approach or is there something I am missing?
This is my stencil.config.ts:
import { Config } from '#stencil/core';
export const config: Config = {
namespace: 'poc',
globalStyle: 'src/global/variables.css',
outputTargets: [
{
type: 'dist',
esmLoaderPath: 'loader'
},
{
type: 'docs-readme'
},
{
type: 'www',
serviceWorker: null // disable service workers
}
],
copy: [
{ src: 'global' }
]
};
The copy property copies the global dir across to dist/collection/. This doesn't resolve the problem either.
This is my package.json:
{
"name": "uwe-ds-poc",
"version": "0.0.9",
"description": "Stencil Component Starter",
"main": "dist/index.js",
"module": "dist/index.mjs",
"es2015": "dist/esm/index.mjs",
"es2017": "dist/esm/index.mjs",
"types": "dist/types/index.d.ts",
"collection": "dist/collection/collection-manifest.json",
"collection:main": "dist/collection/index.js",
"unpkg": "dist/poc/poc.js",
"files": [
"dist/",
"loader/"
],
"scripts": {
"build": "stencil build --docs",
"start": "stencil build --dev --watch --serve",
"test": "stencil test --spec --e2e",
"test.watch": "stencil test --spec --e2e --watchAll",
"generate": "stencil generate"
},
"devDependencies": {
"#stencil/core": "^1.8.1",
"#types/jest": "^24.0.23",
"#types/puppeteer": "1.20.2",
"jest": "^24.9.0",
"jest-cli": "24.8.0",
"puppeteer": "1.20.0"
},
"license": "MIT"
}
This entire Stencil project is here.
Thanks in advance.

Importing the unpkg cdn is a valid option.
However if you are using a bundler (webpack, parcel, etc.) you could just import your css with something like import 'my-package/dist/path/to/global.css'.

Related

How to import js module when Typescript declaration file is located in a separate directory?

Question:
When I run npm run build with the configuration below, rollup.js is unable to resolve the dependency (import) and displays the following message below. Is there any way to make rollup happy while also referencing the Typescript declaration file?
Message from rollup:
(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
pdfjs-dist/types/web/ui_utils (imported by index.ts)
Here is my index.ts:
import { RendererType } from 'pdfjs-dist/types/web/ui_utils'
const renderType = RendererType.CANVAS;
My package.json:
{
"name": "myproject",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "rollup --config"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"#rollup/plugin-node-resolve": "^13.2.1",
"#rollup/plugin-typescript": "^8.3.2",
"pdfjs-dist": "^2.13.216",
"rollup": "^2.70.2",
"typescript": "^4.6.4"
}
}
My rollup.config.js:
import typescript from '#rollup/plugin-typescript';
import { nodeResolve } from '#rollup/plugin-node-resolve';
export default [
{
input: 'index.ts',
output: {
format: 'es',
file: 'index.js'
},
plugins: [
typescript(),
nodeResolve({ browser: true })
]
}
]
Here are the exact steps to reproduce the error above:
Create an empty folder and then run npm -y init
Run the following command:
npm install typescript pdfjs-dist rollup #rollup/plugin-node-resolve #rollup/plugin-typescript --save-dev
Add "build": "rollup --config" to your package.json
Create the rollup.config.js file shown above
Run npm run build in the terminal
More background:
Now, I should point out that the file pdfjs-dist/types/web/ui_utils is a typescript declaration file (ui_utils.d.ts). The actual js file is in pdfjs-dist/lib/web.
If I copy the typescript declaration file so that it is located in the same directory as the js file, dependency resolution works. However, since I will be writing a wrapper around pdf js, I would have to do this for every typescript declaration file which is very tedious and upgrading would also become an issue.
So another way to word the question would be how to resolve a module *.d.ts when the js file is located in another directory?
I came up with the following solution to the problem.
Create a d.ts with the following and name it the same as the module name (ui_utils.d.ts in my case)
declare module 'pdfjs-dist/lib/web/ui_utils' {
export * from 'pdfjs-dist/types/web/ui_utils'
}
Using the above, now I can reference the actual location of the module and Typescript will pick up the declarations as well.
import { RendererType } from 'pdfjs-dist/lib/web/ui_utils'
Side note: When using rollup, you may also need to use #rollup/plugin-commonjs to be able to resolve dependencies.

What is causing my tsx to render properly without babel in react app?

Recently I tried to make a react app using typescript and webpack, after playing around with the setup, I found out I was able to run my app (display hello world in the browser) without installing any babel installations that I would normally install (babel-loader/core/preset-env).
To give more context, most of my files were .tsx instead of .jsx, and I'm using ES6 syntax, I am aware that my app wasn't able to identify jsx files and I assume it was because I didn't install babel, but that made me wonder why the .tsx files were able to work properly when displayed on the browser, I did need to install the ts-loader and did some configurations in the webpack.config.js file setting .tsx as one of the file extensions to resolve(webpack.config.js is shown below), but that still made me wonder if that was the reason I didn't need babel.
I guess my main confusion is that I always thought babel was needed to interpret jsx, I know that tsx is a different file extension type, but isn't it kind of like a superset of jsx like ts is to js? I'm just curious why my react app that has HTML-like syntax in my components was able to work without installing babel. I also couldn't find any babel installations in node modules folder so looks like no library I used is using babel under the hood.
In my scenario, seems like babel is not needed for tsx rendering, are there any features that babel provides that might make me want to use it? I know babel can translate ES6 to older version javascript but I can also accomplish that with config settings.(I asked this follow up question mainly because I still see some people have it in their typescript react app, also I only just made a text display on the browser, so I'm not sure if I will run into any other issues if I do not have babel installed)
Thanks to anyone who can answer my question.
To give more info , I have my app settings below
tsconfig.json :
{
"compilerOptions": {
"module": "commonjs",
"jsx": "react",
"watch": true,
"target": "es5",
"lib": ["es6","dom"],
"esModuleInterop": true
}
}
webpack.config.js :
'use strict';
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
entry: './src/index.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.tsx$/,
exclude: /node_modules/,
use: 'ts-loader'
}
]
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
})
],
devServer: {
contentBase: path.join(__dirname, 'dist'),
port: 9000
},
optimization: {
minimizer: [new UglifyJsPlugin()]
}
};
sample code :
index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import Header from './Header';
ReactDOM.render(
<h1>
react-typescript
<Header text={'hello world'} />
</h1>,
document.querySelector('#root')
);
Header.tsx :
import React from 'react';
export interface HeaderProps {
text: string;
num?: number;
}
const Header: React.FC<HeaderProps> = ({ text }) => {
return <div>{text}</div>;
};
export default Header;
package.json :
{
"name": "ts-react",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "./node_modules/.bin/webpack",
"build:watch": "./node_modules/.bin/webpack -w",
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack serve --mode development --env development --hot"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
"devDependencies": {
"#types/node": "^14.14.28",
"#types/react": "^17.0.2",
"#types/react-dom": "^17.0.1",
"html-webpack-plugin": "^5.1.0",
"ts-loader": "^8.0.17",
"typescript": "^4.1.5",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "^5.22.0",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.11.2"
}
}
Pretty much the same as was already commented, ts-loader is going to compile your .ts .tsx files into targeted versions of javascript from your tsconfig. Babel isn't necessary for typescript projects, but can come with some additional features like being able to transpile for specific browser versions, as well as some performance gains because it doesn't actually type check.

Compiling React projects in MonoRepo failing

I'm trying to setup yarn workspaces with my docker instance. This is my directory structure:
/monorepo/
/node_modules/
#libs/common
#services/common
#services/project-A
...OTHER DEPS...
package.json
/services/
/common/
index.jsx
package.json
/project-A/
webpack.base.config.js
**REACT project with babel, webpack, etc**
/libs/
/tools/
/common/
index.jsx
package.json
To simplify my docker setup I just configured this volume within my docker compose that maps the entire monorepo directory:
volumes:
- '../../../monorepo:/monorepo'
From there in my Project-A I import #libs/common and #services/common. This works fine when the common libraries are exporting simple functions like:
export const Add = (a,b) => a+b
Webpack has no issue resolving this and building Project-A.
However when I try to import a component from one of the common libraries like this:
/libs/tools/common:
import React from 'react'
export MySharedComponent = () => <>HELLLO</>
I get an error in the build process:
Error: Cannot find module '/monorepo/libs/tools/common/webpack.base.config.js'
Require stack:
- /monorepo/node_modules/eslint-import-resolver-webpack/index.js
- /monorepo/node_modules/eslint-module-utils/resolve.js
- /monorepo/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
- /monorepo/node_modules/eslint-plugin-import/lib/index.js
The eslint file under Project-A:
{
"parser": "babel-eslint",
"env": {
"browser": true,
"node": true,
"jest": true,
"cypress/globals": true
},
"settings": {
"import/resolver": {
"webpack": {
"config": "webpack.base.config.js"
}
}
}
}
The babel.rc under Project-A
{
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": "current"
}
}
],
"#babel/preset-react",
"#babel/preset-flow"
],
"env": {
"test": {
"plugins": [
[
"babel-plugin-webpack-alias",
{
"config": "./webpack.base.config.js"
}
]
]
}
}
}
My Question:
Is the main issue that there's no webpack config set up in the common repositories. Therefore the workspace does not know how to compile my shared resources?
Should there only be 1 webpack build config in my workspace used by all projects within the workspace? Currently I only have 1 config under Project-A?
What happens if I have specific webpack needs per project, does 1 config (if that's the answer) make sense?
1) First, there is a line in your code that you are referring to webpack.base.config.js in both babelrc and eslint,
so if that file does not exist, this error that says module not found makes sense.
2) Second: if you build and use your repositories in the same situation and environment, yes you can have one config for both but you might need environment setup (Development, Production) for your config.
But if you really want to make your dependencies and configs apart, webpack support multiple entries for your project which you can check that out.

Meteor + LitElement (Polymer 3) issue with importing

I had an issue with importing the LitElement module into a Meteor project:
I'm starting a new test project with Meteor 1.7+ and am using LitElement for a few components.
I installed Meteor like so:
meteor create meteor-lithtml --release 1.7.1-beta.29 --bare
I installed like so:
meteor npm install --save #polymer/lit-element
My node_modules directory looks like so:
My package.json file:
{
"name": "myapp",
"private": true,
"scripts": {
"start": "meteor run"
},
"dependencies": {
"#babel/runtime": "^7.0.0-beta.56",
"#polymer/lit-element": "^0.5.2",
"#vaadin/router": "^1.0.0",
"meteor-node-stubs": "^0.4.1",
"redux": "^4.0.0"
},
"meteor": {
"mainModule": {
"client": "client/index.js",
"server": "server/index.js"
}
}
}
The typical way I see lit-element imported is not working...
Just adding an index.js file and importing the lit-element module generates errors. If I remove the import from the index.js file, the errors go away.
\\ client\index.js
import { LitElement, html } from '#polymer/lit-element';
The very first error:
Uncaught SyntaxError: Unexpected token {
modules.js?hash=182125a3fa97eaa24f6d313584ca593c3aed2103:984
Points to this location:
Expanding node_modules to look into this file:
Why am I getting the unexpected { token?
NOTE: I'm asking this question here just in case a Meteor user stumbles by with the same issue and needs help.
Just in case we have any more Meteor users stop by with an issue like this, here are the references to the explanation & solution:
explanation: https://forums.meteor.com/t/litelement-import-litelement-html/45042/8?u=aadams
solution: https://github.com/aadamsx/meteor-lithtml/pull/1

Simple Vue component not rendering

I am trying to learn Vue.JS, and the component I have made is not rendering on the page. This is my component:
import Vue from 'vue'
const card = new Vue({
el: '#card',
data: {
title: 'Dinosaurs',
content: '<strong>Dinosaurs</strong> are a diverse group of animals
from the clade <em>Dinosauria</em> that first appeared at the Triassic
period.'
}
})
This is my html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue Practice</title>
</head>
<body>
<div id="card">
<header>{{ title }}</header>
<div v-html="content"></div>
</div>
<script src="bundle.js"></script>
</body>
</html>
And this is package.json (I realize most of the dependencies belong in devDependencies):
{
"name": "vue-practice",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"bundle": "browserify -t babelify -t vueify -e main.js >
bundle.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babelify": "^7.3.0",
"browserify": "^14.4.0",
"vue": "^2.4.2",
"vueify": "^9.4.1"
},
"devDependencies": {}
}
When I load index.html in the browser, all it renders is {{ title }} and I am receiving no errors. Any explanation as to why this is happening would be appreciated!
vueify only transforms *.vue files, if you are going to use templating in your index.html then you need Vue compiler in order to compile the template in the browser (https://v2.vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only).
A good way to have things like that covered is to use a vuejs-template, if you are using Browserify there is one: https://github.com/vuejs-templates/browserify
But as you have almost everything up, you can only add what's missing for the compiler package, as stated in "Runtime + Compiler vs. Runtime-only" - "Browserify" section in Vue guide.
Add to your package.json:
{
"browser": {
"vue": "vue/dist/vue.common.js"
},
}
That will tell Browserify to use the full (also called standalone) Vue build on browser.
Another way is to not use templates in index.html but instead in a main component, like App.vue, for that you check out the template I linked above, it does it out of the box.

Categories

Resources