Packaging imported javascript into svelte component using rollup - rollupjs

In my code, I want to import an external javascript file that is common across multiple components. When rollup builds the component, however, it has trouble resolving the imported dependency so it never gets included in the output package. Note, I'm trying to build a svelte component (as opposed to a svelte app) although I'm not sure that makes a difference. Here is my rollup.config.js:
import svelte from 'rollup-plugin-svelte';
import pkg from './package.json';
const name = pkg.name
.replace(/^(#\S+\/)?(svelte-)?(\S+)/, '$3')
.replace(/^\w/, m => m.toUpperCase())
.replace(/-\w/g, m => m[1].toUpperCase());
export default {
input: 'src/Radar.html',
output: [
{ sourcemap: true, file: pkg.module, 'format': 'es' },
{ sourcemap: true, file: pkg.main, 'format': 'umd', name }
],
plugins: [
svelte({
cascade: false,
store: true
})
]
};

To resolve dependency there is a plugin for Rollup:
import svelte from 'rollup-plugin-svelte';
import resolve from '#rollup/plugin-node-resolve';
import pkg from './package.json';
const name = pkg.name
.replace(/^(#\S+\/)?(svelte-)?(\S+)/, '$3')
.replace(/^\w/, m => m.toUpperCase())
.replace(/-\w/g, m => m[1].toUpperCase());
export default {
input: 'src/Radar.html',
output: [
{ sourcemap: true, file: pkg.module, 'format': 'es' },
{ sourcemap: true, file: pkg.main, 'format': 'umd', name }
],
plugins: [
svelte({
cascade: false,
store: true
}),
resolve()
]
};
I assume that Radar.html is a Svelte module, i.e. you can rename it to Radar.svelte.

Related

Import image with vanilla-extract and esbuild

I have a problem with images importing using vanilla-extract and esbuild
my build file:
const { build } = require("esbuild");
const { vanillaExtractPlugin } = require("#vanilla-extract/esbuild-plugin");
(async () => {
await build({
entryPoints: ["src/entry.tsx"],
bundle: true,
minify: true,
sourcemap: true,
platform: "browser",
outfile: "dist/entry.js",
plugins: [vanillaExtractPlugin()],
loader: {
".svg": "file",
},
});
})();
my entry.tsx
import { someStyle } from "./style.css";
console.log(someStyle);
When i importing my image in "css" way
import { style } from "#vanilla-extract/css";
export const someStyle = style({
backgroundColor: "url(./x.svg)",
});
The compiler return error
Could not resolve "./x.svg" (the plugin "vanilla-extract" didn't set a resolve directory)`
If i am trying to import x.svg using the typescript import
import { style } from "#vanilla-extract/css";
import svg from "./x.svg";
export const someStyle = style({
backgroundColor: `url(${svg})`,
});
I have other error
src/style.css.ts:5:16: error: No loader is configured for ".svg" files: src/x.svg'
Is it possible to import images with vanilla-extract modules without marking them as external?
It not working now. Workaround is to use babel
import babel from 'esbuild-plugin-babel';
plugins: [
babel({
filter: /.*.css.ts/,
config: {
presets: ['#babel/preset-typescript'],
plugins: ['#vanilla-extract/babel-plugin'],
},
}),
],

Rollup Error in pnpm-workspace monorepo:'default' is not exported by ../../node_modules/.pnpm/classnames#2.3.1/node_modules/classnames/index.js

I have a UI lib repo , which could working well with below rollup config
My rollup.conf.js
import babel from '#rollup/plugin-babel';
import commonjs from '#rollup/plugin-commonjs';
import json from '#rollup/plugin-json';
import postcss from 'rollup-plugin-postcss';
import { nodeResolve } from '#rollup/plugin-node-resolve';
import { terser } from 'rollup-plugin-terser';
import typescript from 'rollup-plugin-typescript2';
import { DEFAULT_EXTENSIONS } from '#babel/core';
const isProd = process.env.NODE_ENV === 'production';
const pkg = require('./package.json');
const dependencies = Object.keys(pkg.peerDependencies);
export default {
input: './components/index.ts',
output: [
{
format: 'umd',
name: pkg.name,
file: 'lib/index.main.js',
globals: {
antd: 'antd',
'antd-mobile': 'antd-mobile',
react: 'react',
'react-dom': 'react-dom',
'styled-components': 'styled-components',
},
},
{
format: 'es',
name: pkg.name,
file: 'lib/index.module.js',
globals: {
antd: 'antd',
'antd-mobile': 'antd-mobile',
react: 'react',
'react-dom': 'react-dom',
'styled-components': 'styled-components',
},
},
],
onwarn: function (warning) {
if (warning.code === 'CIRCULAR_DEPENDENCY') {
return;
}
if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; };
console.error(`(!) ${warning.message}`);
},
plugins: [
typescript({
include: ['*.ts+(|x)', '**/*.ts+(|x)'],
exclude: 'node_modules/**',
typescript: require('typescript'),
}),
babel({
exclude: 'node_modules/**',
babelHelpers: 'runtime',
extensions: [...DEFAULT_EXTENSIONS, '.ts', 'tsx'],
}),
nodeResolve({
mainField: ['jsnext:main', 'browser', 'module', 'main'],
browser: true,
}),
commonjs(),
json(),
postcss({
// Minimize CSS, boolean or options for cssnano.
minimize: isProd,
// Enable sourceMap.
sourceMap: !isProd,
// This plugin will process files ending with these extensions and the extensions supported by custom loaders.
extensions: ['.less', '.css'],
use: [['less', { javascriptEnabled: true, modifyVars: { '#primary-color': '#42b983' } }]],
}),
isProd && terser(),
],
external: dependencies,
};
however , when i am using pnpm workspace and try to manage it inside , below error showing:
The Error I'm getting and don't know to solve
[!] Error: 'default' is not exported by ../../node_modules/.pnpm/classnames#2.3.1/node_modules/classnames/index.js, imported by ../../node_modules/.pnpm/antd#4.16.13_react-dom#16.13.1+react#16.13.1/node_modules/antd/es/empty/index.js
https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module
../../node_modules/.pnpm/antd#4.16.13_react-dom#16.13.1+react#16.13.1/node_modules/antd/es/empty/index.js (18:7)
16:
17: import * as React from 'react';
18: import classNames from 'classnames';
^
19: import { ConfigContext } from '../config-provider';
20: import LocaleReceiver from '../locale-provider/LocaleReceiver';
Error: 'default' is not exported by ../../node_modules/.pnpm/classnames#2.3.1/node_modules/classnames/index.js, imported by ../../node_modules/.pnpm/antd#4.16.13_react-dom#16.13.1+react#16.13.1/node_modules/antd/es/empty/index.js
at error (/Users/yejinlei/Documents/playground/personal/pnpm-workspace/node_modules/.pnpm/rollup#2.57.0/node_modules/rollup/dist/shared/rollup.js:158:30)
at Module.error (/Users/yejinlei/Documents/playground/personal/pnpm-workspace/node_modules/.pnpm/rollup#2.57.0/node_modules/rollup/dist/shared/rollup.js:12339:16)
at Module.traceVariable (/Users/yejinlei/Documents/playground/personal/pnpm-workspace/node_modules/.pnpm/rollup#2.57.0/node_modules/rollup/dist/shared/rollup.js:12724:29)
at ModuleScope.findVariable (/Users/yejinlei/Documents/playground/personal/pnpm-workspace/node_modules/.pnpm/rollup#2.57.0/node_modules/rollup/dist/shared/rollup.js:11517:39)
 ELIFECYCLE  Command failed with exit code 1.
the https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module page does not really help, since the namedExports has been no longer working.
"#babel/core": "^7.12.9",
"#rollup/plugin-babel": "^5.2.2",
"#rollup/plugin-commonjs": "^17.0.0",
"#rollup/plugin-json": "^4.1.0",
"#rollup/plugin-node-resolve": "^11.0.0",
"rimraf": "3.0.2",
"rollup-plugin-postcss": "^4.0.1",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.30.0",
"tslib": "^2.0.3",
"typescript": "^4.1.2"
its a lib repo that integrated with antd. antd-mobile, which currently using React for UI development.
Try regex in rollup.config.js under plugins:
babel({
babelHelpers: "bundled",
exclude: /node_modules/, // add this
}),

No such file or directory, when using Vite and Antd Pro Layout

No such file or directory, when using Vite and Antd Pro Layout
This is file vite.config.ts:
import { defineConfig } from 'vite';
import reactRefresh from '#vitejs/plugin-react-refresh';
import path from 'path';
import vitePluginImp from 'vite-plugin-imp';
export default defineConfig({
plugins: [
reactRefresh(),
vitePluginImp({
libList: [
{
libName: 'antd',
style: (name) => {
return `antd/lib/${name}/style/index.less`;
},
},
],
}),
],
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
modifyVars: {
...{
'primary-color': '#1DA57A',
'link-color': '#1DA57A',
'border-radius-base': '2px',
},
},
},
},
},
resolve: {
alias: [
{
find: /^~/,
replacement: path.resolve(__dirname, 'src'),
},
],
},
optimizeDeps: {
include: ['#ant-design/icons'],
},
});
This is my config to using antd, antd-pro-layout with vite.
But I received the error:
[vite] Internal server error: ENOENT: no such file or directory, open
'/Users/tranthaison/DEV/vite2-react-ts/srcantd/es/style/themes/default.less'
Can someone help me to fix it?
I had some problems when using React + Antd in Vite.
Thanks for #theprimone for the answer. But the answer is incomplete. I will complete the answer here.
First time, add additional config to Less Preprocessor:
Add this config to your vite.config.js file:
{
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
},
},
},
}
Second, setting module aliases to fix Less #import problem:
Again, add the following config into your vite.config.js file:
{
resolve: {
alias: [
{ find: /^~/, replacement: "" },
],
},
}
Last, install vite-plugin-imp plugin to solve Antd ES problem:
Install the vite-plugin-imp dependencies:
pnpm add -D vite-plugin-imp
# or
npm i -D vite-plugin-imp
then, setup the plugin in your vite.config.js file:
{
plugins: [
// React plugin here
vitePluginImp({
libList: [
{
libName: "antd",
style: (name) => `antd/es/${name}/style`,
},
],
}),
];
}
The final configuration in vite.config.js file will look like this:
import { defineConfig } from "vite";
import reactRefresh from '#vitejs/plugin-react-refresh';
import vitePluginImp from "vite-plugin-imp";
export default defineConfig({
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
},
},
},
resolve: {
alias: [
{ find: /^~/, replacement: "" },
],
},
plugins: [
reactRefresh(),
vitePluginImp({
libList: [
{
libName: "antd",
style: (name) => `antd/es/${name}/style`,
},
],
}),
],
});
Also work with #preact/preset-vite.
Ref:
https://github.com/theprimone/vite-react
https://github.com/ant-design/ant-design/issues/7850
https://github.com/vitejs/vite/issues/2185#issuecomment-784637827
Try to import antd styles like this:
vitePluginImp({
libList: [
{
libName: 'antd',
style: (name) => `antd/es/${name}/style`,
},
],
}),
More usage of Vite + React + Ant Design or other UI Library, this repo theprimone/vite-react might give you more or less inspiration.

ng-bootstrap AoT build failure with Unexpected Token and missing loader

I am trying to use ng-bootstrap library in my project. Runs fine with webpackdevserver and jit build but aot build throw errors similar to following
Module parse failed: E:\SVNCode\Learning\spa\aot\node_modules\#ng-
bootstrap\ng-bootstrap\alert\alert.ngfactory.ts Unexpected token (13:21)
You may need an appropriate loader to handle this file type.
I have searched for the issue but the only reference related to ng-bootstrap was ticket no. #1381 on github, which was closed without any further details. So, I believe that I may be missing something very small. Here are relevant details
Node : 8.1.3
Angular & Compiler-cli: 4.2.4
Webpack : 2.6.1
typescript : 2.3.4
ng-bootstrap : 1.0.0-alpha.26
bootstrap : 4.0.0-alpha.6 (using CDN but tried after install also with
same result)
webpack.prod.js
let ExtractTextPlugin = require('extract-text-webpack-plugin');
let webpack = require('webpack');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let CompressionPlugin = require("compression-webpack-plugin");
let CopyWebpackPlugin = require('copy-webpack-plugin');
let path = require('path');
let rootDir = path.resolve(__dirname, '..');
module.exports = {
entry: {
'polyfills': './spa/polyfills.ts',
'vendor': './spa/vendor-aot.ts',
'app': './spa/main-aot.ts' // AoT compilation
},
output: {
path: path.join(rootDir,'wwwroot'),
filename: 'js/[name]-[hash:6].bundle.js',
chunkFilename: 'js/[id]-[hash:6].chunk.js',
publicPath: '/'
},
resolve: {
extensions: ['.ts', '.js', '.json', '.css', '.html']
},
module: {
rules: [
{
test: /\.ts$/,
use: [
'babel-loader?presets[]=es2015',
'awesome-typescript-loader?configFileName=tsconfig-aot.json',
'angular-router-loader?aot=true&genDir=spa/aot/'
],
exclude: /node_modules/
},
{
test: /\.css$/,
loaders: ['to-string-loader', 'css-loader']
},
{
test: /\.html$/,
use: 'html-loader'
}
],
exprContextCritical: false
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
}),
new webpack.optimize.UglifyJsPlugin({
beautify: false,
compress: {
warnings: false
},
output: {
comments: false
},
sourceMap: false,
mangle: {keep_fnames: true}
}),
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.html$/,
threshold: 10240,
minRatio: 0.8
}),
new ExtractTextPlugin("[name].css"),
new HtmlWebpackPlugin({
template: './spa/index.html'
}),
new CopyWebpackPlugin([
{ from: path.join(rootDir,'spa','assets'), to: 'assets'}
]),
new webpack.NoEmitOnErrorsPlugin()
]
};
tsconfig-aot.js
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"lib": ["es2015","dom"],
"typeRoots": ["node_modules/#types"],
"types":["node", "core-js"]
},
"files": [
"spa/app/app.module.ts",
"spa/main-aot.ts"
],
"exclude": ["node_modules"],
"angularCompilerOptions": {
"genDir": "spa/aot",
"skipMetadataEmit": true
},
"awesomeTypescriptLoaderOptions":{
"useWebpackText": true,
"useCache": true
}
}
vendor-aot.ts
import '#angular/platform-browser';
import '#angular/core';
import '#angular/common';
import '#angular/http';
import '#angular/forms';
import '#angular/router';
import '#angular/platform-browser/animations';
import 'rxjs';
//can import others e.g. bootstrap, jquery etc
//can import js, ts, css, sass etc..
import '#ng-bootstrap/ng-bootstrap';
Thanks & Regards
After searching the internet high and low, going through several stackoverflow posts and github project configurations/samples, I finally managed to fix it (duct tape way).
All I had to do to fix the issue was remove the exclusion of node_modules folder in webpack config file.
Now, WHY exclusion of node_modules works for angular and rxjs packages but not for ng-bootstrap, is still beyond me.
Exclusion works when building for jit but for aot to succeed node_modules HAS TO BE INCLUDED in ts loader chain. Now the build time for aot has increased multifold, but at least it works.

Nicer class names in PostCSS

I'm building my app using Webpack 2. I'm using PostCSS 2 for CSS modules. Here is my CSS importing configuration for Webpack:
{
test: /\.css$/,
exclude: /(node_modules)/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
},
},
{
loader: 'postcss-loader',
options: {
plugins: loader => [
require("postcss-import")({
path: './js',
addDependencyTo: webpack,
}),
require('postcss-cssnext')(),
],
},
},
],
},
Now, the problem is, that this generates really ugly class names. Example using React:
import React, {Component} from 'react';
import styles from './Element.css';
export default class Element extends Component{
render(){
return (
<div className={styles.myElement}>This is an example.</div>
);
}
}
Renders into:
<div class="_1DHVkmCxFFQMFYac-L_MIg">This is an example.</div>
Now, this is fine in production, but in development, something like class="myElement--_1DHVkmCxFFQMFYac-L_MIg" would be a lot nicer. I found a GitHub issue discussing this, but as I'm new to Webpack, I couldn't figure out how to implement their suggestion. Whatever I tried resulted in an error, where Webpack couldn't resolve the module.
I tried adding localIdentName: '[local]--[hash:base64:5]' to postcss-loader options, but that did nothing.
So, how do I retain the original class name in the generated class name?
Adding this line to the css-loader resolved it:
localIdentName: debug ? '[name]_[local]___[hash:base64:10]' : undefined,
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
minimize: false, //this line!!
},
},
you can use minimize: !isDebug and isDebug is a bool to know if you are debugging or not. but setting to false should leave "nice names"

Resources