Develop a library of components using TypeScript and Less files

I'm currently in the process of creating a React UI library that will consist of various components such as Buttons, Inputs, textareas, etc. This library, which I've temporarily named mylib, will be reused across multiple projects including one called myApp. To ensure type safety, I plan to use TypeScript which requires compilation to ES6. Additionally, I'll be using .less files for styling purposes.

My main concern revolves around handling the .less files. Should I compile them within the myLib itself or delegate this task to the myApp? Is it sufficient to rely solely on the TypeScript compiler, or would it be beneficial to incorporate Webpack for any specific reasons? Despite my efforts, I remain uncertain whether my current approach is the most effective one.

My proposed strategy involves compiling TypeScript code within myLib, while allowing myApp to handle the .less files: Initially, I organize the source code in the src folder and compile it into a destination folder named dist with the TypeScript compiler. Subsequently, by executing a designated script, I copy the relevant .less files from src to dist while preserving their relative paths using the command

cd src && find .  -name '*.less' -exec rsync -R {} ../dist ';'
.

This outlines the directory structure of mylib before compilation:

.
├── README.md
├── dist // destination folder
├── package.json
├── src
│   ├── components
│   │   └── MyComponent
│   │       ├── MyComponent.less
│   │       └── MyComponent.tsx
│   ├── css
│   │   ├── constants.less
│   │   ├── imports.less
│   │   └── reset.less
│   └── index.tsx
└── tsconfig.json

Here's the contents of MyComponent.tsx:

import React from 'react';
import './MyComponent.less';

class MyComponent extends React.Component {
    render() {
        return <div className="MyComponent">My component</div>;
    }
}

export default MyComponent;

This demonstrates the content of MyComponent.less:

@c: .MyComponent;

@{c} {
    font-size: 20px;
    color: tomato;
}

The configuration details specified in tsconfig.json are as follows:

{
  "compilerOptions": {
    "target": "es6",
    "module": "esnext",
    "jsx": "react",
    "esModuleInterop": true,
    "moduleResolution": "node",
    "outDir": "dist"
  }
}

Furthermore, the accompanying package.json contains these specifications:

{
  "name": "@me/mycomponents",
  "version": "0.0.0",
  "description": "Components library",
  "scripts": {
    "build": "tsc -d && cd src && find .  -name '*.less' -exec rsync -R {} ../dist ';' && cd .."
  },
  "devDependencies": {
    "typescript": "^3.6.2",
    "react-dom": "^16.9.0"
  },
  "dependencies": {
    "prop-types": "^15.7.2",
    "react": "^16.9.0",
  }
}

Upon completion of compilation, the structure transforms into:

.
├── README.md
├── dist
│   ├── components
│   │   └── MyComponent
│   │       ├── MyComponent.d.ts
│   │       ├── MyComponent.js
│   │       └── MyComponent.less
│   ├── css
│   │   ├── constants.less
│   │   ├── imports.less
│   │   └── reset.less
│   ├── index.d.ts
│   └── index.js
├── package.json
├── src
│   ├── components
│   │   └── MyComponent
│   │       ├── MyComponent.less
│   │       └── MyComponent.tsx
│   ├── css
│   │   ├── constants.less
│   │   ├── imports.less
│   │   └── reset.less
│   └── index.tsx
└── tsconfig.json

Therefore, once imported into myApp, MyComponent should seamlessly integrate with the ability to compile the associated less files within the same environment.

Does this methodology align with your expectations?

Answer №1

Should I compile the less files in myLib or myApp?

  • Your component library should provide both the .less source code and the .css output.

  • .css is useful for non-less consumers who still want to use your styles.

  • .less is beneficial for less-consumers who may utilize less-specific features like mixins.

Is it sufficient to use only TypeScript compiler, or would it be better to also incorporate Webpack for any reasons?

  • Ideally, your component library should rely solely on the typescript compiler to generate the dist/**/*.js files.

  • Bundling, minification, optimization, polyfilling, and similar concerns should be handled by the consuming applications.

  • Ensure that your tsconfig.json is configured to produce .d.ts declaration files alongside the javascript output to benefit typescript users with typings, code hints, and auto-completion.

    • Add "declaration": true to your `tsconfig.json`.
    • You may also consider enabling source maps for debugging with "sourceMap": true.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue: Module 'ansi-styles' not found when using AngularJS and Yeoman generator

Previously my code was functioning perfectly, but now it seems to have suddenly stopped working. Attempting yo angular:route api resulted in the following error message: Error: Cannot find module 'ansi-styles' at Function.Module._resolveFilen ...

Issue: Prior to initiating a Saga, it is imperative to attach the Saga middleware to the Store using applyMiddleware function

I created a basic counter app and attempted to enhance it by adding a saga middleware to log actions. Although the structure of the app is simple, I believe it has a nice organizational layout. However, upon adding the middleware, an error occurred: redu ...

Incorporate Angular frontend into current website or project

I've successfully built a website using bootstrap, but now I'm looking to integrate Angular in order to transform it into a single page application. The goal is that when a user clicks on a link, only the necessary content will be loaded from the ...

How can we eliminate all elements from jQuery except for the first and second elements?

HTML <div class="geo_select"> <h3>header 3</h3> in Above HTML code i want to remove all element except <h3> and default content<div> inside the <div class='geo_select'> in jquery.. How to remove all ...

What is the most effective way to retrieve the value of a child component in Angular 2 and pass it to the parent component?

I am working on a project with a child component (calendar) and a parent component (form). I need to select a value in the calendar and then access that value in the form component. What is the best way to achieve this? Child Component.ts: import { ...

In my attempts to retrieve specific statistics from the PokeAPI using Axios and Node.js, I encountered an error

Having an issue while trying to utilize the Pokemon API. Whenever attempting to access the attack, HP and speed stats, all Pokemons show up as undefined! Can someone please point out what might be wrong with my API call? const axios = require('axios&a ...

Resolving the CORS preflight issue with Loopback API in Redux

My current setup involves a client application running on React-Redux and an API app on Loopback. During local testing, I have the client app on port 8080 and the server app on port 3000. While attempting to test Google OAuth (using the loopback-passport ...

Enhance your user interface by customizing the expand icon in the React material

Currently, I am utilizing Material-table with a focus on Tree-data. You can find detailed information about this feature here: https://material-table.com/#/docs/features/tree-data. While attempting to implement the provided example, I am encountering diff ...

What is the method for ensuring TypeScript automatically detects the existence of a property when an object is statically defined?

In my software, I have an interface that serves as a base for other types. To simplify things for this discussion, let's focus on one specific aspect. This interface includes an optional method called getColor. I am creating an object that implements ...

Creating a row of aligned card components in React

Recently, I began learning React and successfully created a card component using Material UI. However, this time around, I'm attempting to create it using axios and map() methods. I expected the cards to be displayed in the same row horizontally, not ...

Get the most recent two files from a set

I am currently facing a challenge in retrieving the first 2 documents from a collection in google cloud firestore. My current approach involves using the timestamp of the latest document and then calculating the time range to fetch the desired documents. l ...

Top solution for preventing text selection and image downloading exclusively on mobile devices

My plan is to use the following code to accomplish a specific goal: -webkit-touch-callout:none; -webkit-user-select:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; -webkit-tap-highlight-color:rgba(0,0,0,0); I& ...

What is the reason for the Circle to Polygon node module producing an oval or ellipse shape instead of a circle shape?

I've been experimenting with the npm package circle-to-polygon and I crafted the following code to generate a polygon that resembles a circle. const circleToPolygon = require('circle-to-polygon'); let coordinates = [28.612484207825005, 77. ...

Children components in Vue.js are receiving an undefined props object

Within my application, I am working with a parent and child component. The parent component directly includes the child component, which needs to access data from the parent. This data is fetched from a REST API within the parent component. However, when t ...

Reorganize components in MongoDB record

Description: Each customer object includes a name field. A line object is comprised of the following fields: inLine - an array of customers currentCustomer - a customer object processed - an array of customers The 'line' collection stores doc ...

Unusual actions observed in ajax rails form calculator with pre-filled values

I have a form calculator in Rails that utilizes AJAX without a database. While it functions properly, I have noticed some peculiar behavior which I would like to address. Firstly, I navigate to the /interest_calculator page Then, I input 10 into @first_0 ...

Tips for transforming a React sign in component into an already existing Material UI sign in component

I am looking to revamp my current sign-in page by transitioning it into a material UI style login page. Displayed below is the code for my existing sign-in component named "Navbar.js". This file handles state management and includes an axios call to an SQ ...

Discovering a value that aligns with one of the values in an array using Javascript

Just a heads up: this quiz is super simple and only has one input field for each question. This block of Javascript code is used to check if the answer entered in the input field is correct or not. In this case, it checks if the answer entered is 'en ...

Having trouble with the nav-item dropdown functionality on Laravel Vue?

Currently utilizing Laravel and Vue.js along with AdminLTE. Initially it was functioning properly, but now... head <!-- Font Awesome Icons --> <link rel="stylesheet" href="plugins/fontawesome-free/css/all.min.css"> <!-- Theme style --> ...

Adding the data from an ajax object response to an array

I'm encountering an issue where my Ajax response is not being properly looped through each object and pushed into the array. I've been stuck on this problem for quite some time now. The Ajax response looks like this... {type:'blog_post&apo ...