2022-01-14 04:11:27 +03:00
|
|
|
/**
|
|
|
|
* Bundles the widgets library, which is released independently of the interface application.
|
|
|
|
* This library lives in src/lib, but shares code with the interface application.
|
|
|
|
*/
|
|
|
|
|
2022-02-08 22:04:48 +03:00
|
|
|
import alias from '@rollup/plugin-alias'
|
|
|
|
import babel from '@rollup/plugin-babel'
|
|
|
|
import commonjs from '@rollup/plugin-commonjs'
|
2022-01-14 04:11:27 +03:00
|
|
|
import json from '@rollup/plugin-json'
|
2022-02-08 22:04:48 +03:00
|
|
|
import resolve from '@rollup/plugin-node-resolve'
|
2022-01-14 04:11:27 +03:00
|
|
|
import replace from '@rollup/plugin-replace'
|
2022-02-08 22:04:48 +03:00
|
|
|
import typescript from '@rollup/plugin-typescript'
|
2022-01-14 04:11:27 +03:00
|
|
|
import url from '@rollup/plugin-url'
|
|
|
|
import svgr from '@svgr/rollup'
|
2022-02-08 22:04:48 +03:00
|
|
|
import path from 'path'
|
|
|
|
import { RollupWarning } from 'rollup'
|
|
|
|
import copy from 'rollup-plugin-copy'
|
|
|
|
import del from 'rollup-plugin-delete'
|
2022-01-14 04:11:27 +03:00
|
|
|
import dts from 'rollup-plugin-dts'
|
2022-03-01 22:32:55 +03:00
|
|
|
// @ts-ignore // missing types
|
|
|
|
import multi from 'rollup-plugin-multi-input'
|
2022-02-08 22:04:48 +03:00
|
|
|
import externals from 'rollup-plugin-node-externals'
|
2022-01-14 04:11:27 +03:00
|
|
|
import sass from 'rollup-plugin-scss'
|
2022-02-08 22:04:48 +03:00
|
|
|
import { CompilerOptions } from 'typescript'
|
2022-01-14 04:11:27 +03:00
|
|
|
|
2022-02-08 22:04:48 +03:00
|
|
|
const REPLACEMENTS = {
|
|
|
|
'process.env.REACT_APP_IS_WIDGET': true,
|
2022-02-11 21:34:03 +03:00
|
|
|
'process.env.REACT_APP_LOCALES': '"./locales"',
|
2022-03-01 22:32:55 +03:00
|
|
|
// esm requires fully-specified paths:
|
|
|
|
'react/jsx-runtime': 'react/jsx-runtime.js',
|
2022-02-08 22:04:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
const EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx']
|
|
|
|
const ASSET_EXTENSIONS = ['.png', '.svg']
|
|
|
|
function isAsset(source: string) {
|
|
|
|
const extname = path.extname(source)
|
|
|
|
return extname && [...ASSET_EXTENSIONS, '.css', '.scss'].includes(extname)
|
|
|
|
}
|
2022-01-14 04:11:27 +03:00
|
|
|
|
2022-03-29 22:00:56 +03:00
|
|
|
function isEthers(source: string) {
|
|
|
|
// @ethersproject/* modules are provided by ethers, with the exception of experimental.
|
|
|
|
return source.startsWith('@ethersproject/') && !source.endsWith('experimental')
|
|
|
|
}
|
|
|
|
|
2022-02-08 22:04:48 +03:00
|
|
|
const TS_CONFIG = './tsconfig.lib.json'
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
|
|
const { baseUrl, paths }: CompilerOptions = require(TS_CONFIG).compilerOptions
|
|
|
|
const aliases = Object.entries({ ...paths }).flatMap(([find, replacements]) => {
|
|
|
|
return replacements.map((replacement) => ({
|
|
|
|
find: path.dirname(find),
|
|
|
|
replacement: path.join(__dirname, baseUrl || '.', path.dirname(replacement)),
|
|
|
|
}))
|
|
|
|
})
|
2022-01-14 04:11:27 +03:00
|
|
|
|
2022-02-08 22:04:48 +03:00
|
|
|
const plugins = [
|
|
|
|
// Dependency resolution
|
|
|
|
resolve({ extensions: EXTENSIONS }), // resolves third-party modules within node_modules/
|
|
|
|
alias({ entries: aliases }), // resolves paths aliased through the tsconfig (babel does not use tsconfig path resolution)
|
|
|
|
|
|
|
|
// Source code transformation
|
|
|
|
replace({ ...REPLACEMENTS, preventAssignment: true }),
|
2022-02-28 18:52:22 +03:00
|
|
|
json(), // imports json as ES6; doing so enables type-checking and module resolution
|
2022-02-08 22:04:48 +03:00
|
|
|
]
|
|
|
|
|
|
|
|
const check = {
|
|
|
|
input: 'src/lib/index.tsx',
|
2022-03-01 22:32:55 +03:00
|
|
|
output: { file: 'dist/widgets.tsc', inlineDynamicImports: true },
|
2022-03-29 22:00:56 +03:00
|
|
|
external: (source: string) => isAsset(source) || isEthers(source),
|
2022-03-01 22:32:55 +03:00
|
|
|
plugins: [
|
|
|
|
externals({ exclude: ['constants'], deps: true, peerDeps: true }), // marks builtins, dependencies, and peerDependencies external
|
|
|
|
...plugins,
|
|
|
|
typescript({ tsconfig: TS_CONFIG }),
|
|
|
|
],
|
2022-02-08 22:04:48 +03:00
|
|
|
onwarn: squelchTranspilationWarnings, // this pipeline is only for typechecking and generating definitions
|
2022-01-14 04:11:27 +03:00
|
|
|
}
|
|
|
|
|
2022-02-08 22:04:48 +03:00
|
|
|
const type = {
|
|
|
|
input: 'dist/dts/lib/index.d.ts',
|
2022-03-01 22:32:55 +03:00
|
|
|
output: { file: 'dist/index.d.ts' },
|
2022-03-29 22:00:56 +03:00
|
|
|
external: (source: string) => isAsset(source) || isEthers(source),
|
2022-02-08 22:04:48 +03:00
|
|
|
plugins: [
|
2022-03-01 22:32:55 +03:00
|
|
|
externals({ exclude: ['constants'], deps: true, peerDeps: true }),
|
2022-02-08 22:04:48 +03:00
|
|
|
dts({ compilerOptions: { baseUrl: 'dist/dts' } }),
|
2022-02-10 19:50:56 +03:00
|
|
|
process.env.ROLLUP_WATCH ? undefined : del({ hook: 'buildEnd', targets: ['dist/widgets.tsc', 'dist/dts'] }),
|
2022-02-08 22:04:48 +03:00
|
|
|
],
|
|
|
|
}
|
|
|
|
|
2022-03-01 22:32:55 +03:00
|
|
|
/**
|
|
|
|
* This exports scheme works for nextjs and for CRA5.
|
|
|
|
*
|
|
|
|
* It will also work for CRA4 if you use direct imports:
|
|
|
|
* instead of `import { SwapWidget } from '@uniswap/widgets'`,
|
|
|
|
* `import { SwapWidget } from '@uniswap/widgets/dist/index.js'`.
|
|
|
|
* I do not know why CRA4 does not seem to use exports for resolution.
|
|
|
|
*
|
|
|
|
* Note that chunks are enabled. This is so the tokenlist spec can be loaded async,
|
|
|
|
* to improve first load time (due to ajv). Locales are also in separate chunks.
|
|
|
|
*
|
|
|
|
* Lastly, note that JSON and lingui are bundled into the library, as neither are fully
|
|
|
|
* supported/compatible with ES Modules. Both _could_ be bundled only with esm, but this
|
|
|
|
* yields a less complex pipeline.
|
|
|
|
*/
|
|
|
|
|
2022-02-08 22:04:48 +03:00
|
|
|
const transpile = {
|
2022-01-14 04:11:27 +03:00
|
|
|
input: 'src/lib/index.tsx',
|
|
|
|
output: [
|
|
|
|
{
|
2022-03-01 22:32:55 +03:00
|
|
|
dir: 'dist',
|
|
|
|
format: 'esm',
|
|
|
|
sourcemap: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
dir: 'dist/cjs',
|
|
|
|
entryFileNames: '[name].cjs',
|
|
|
|
chunkFileNames: '[name]-[hash].cjs',
|
2022-01-14 04:11:27 +03:00
|
|
|
format: 'cjs',
|
2022-03-01 22:32:55 +03:00
|
|
|
sourcemap: false,
|
2022-01-14 04:11:27 +03:00
|
|
|
},
|
|
|
|
],
|
2022-03-29 22:00:56 +03:00
|
|
|
external: isEthers,
|
2022-01-14 04:11:27 +03:00
|
|
|
plugins: [
|
2022-03-01 22:32:55 +03:00
|
|
|
externals({
|
|
|
|
exclude: [
|
|
|
|
'constants',
|
|
|
|
/@lingui\/(core|react)/, // @lingui incorrectly exports esm, so it must be bundled in
|
|
|
|
/\.json$/, // esm does not support JSON loading, so it must be bundled in
|
|
|
|
],
|
|
|
|
deps: true,
|
|
|
|
peerDeps: true,
|
|
|
|
}),
|
2022-02-08 22:04:48 +03:00
|
|
|
...plugins,
|
|
|
|
|
|
|
|
// Source code transformation
|
2022-02-28 18:52:22 +03:00
|
|
|
url({ include: ASSET_EXTENSIONS.map((extname) => '**/*' + extname), limit: Infinity }), // imports assets as data URIs
|
2022-01-14 04:11:27 +03:00
|
|
|
svgr({ exportType: 'named', svgo: false }), // imports svgs as React components
|
2022-02-28 18:52:22 +03:00
|
|
|
sass({ output: 'dist/fonts.css' }), // generates fonts.css
|
2022-02-08 22:04:48 +03:00
|
|
|
commonjs(), // transforms cjs dependencies into tree-shakeable ES modules
|
|
|
|
|
|
|
|
babel({
|
|
|
|
babelHelpers: 'runtime',
|
|
|
|
presets: ['@babel/preset-env', ['@babel/preset-react', { runtime: 'automatic' }], '@babel/preset-typescript'],
|
|
|
|
extensions: EXTENSIONS,
|
|
|
|
plugins: [
|
|
|
|
'macros', // enables @lingui and styled-components macros
|
|
|
|
'@babel/plugin-transform-runtime', // embeds the babel runtime for library distribution
|
|
|
|
],
|
|
|
|
}),
|
2022-03-01 22:32:55 +03:00
|
|
|
],
|
|
|
|
onwarn: squelchTypeWarnings, // this pipeline is only for transpilation
|
|
|
|
}
|
2022-02-08 22:04:48 +03:00
|
|
|
|
2022-03-01 22:32:55 +03:00
|
|
|
const locales = {
|
|
|
|
input: 'src/locales/*.js',
|
|
|
|
output: [
|
|
|
|
{
|
|
|
|
dir: 'dist',
|
|
|
|
format: 'esm',
|
|
|
|
sourcemap: false,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
plugins: [
|
2022-02-08 22:04:48 +03:00
|
|
|
copy({
|
|
|
|
copyOnce: true,
|
2022-03-01 22:32:55 +03:00
|
|
|
targets: [{ src: 'src/locales/*.js', dest: 'dist/cjs/locales', rename: (name) => `${name}.cjs` }],
|
2022-02-08 22:04:48 +03:00
|
|
|
}),
|
2022-03-01 22:32:55 +03:00
|
|
|
commonjs(),
|
|
|
|
multi(),
|
2022-01-14 04:11:27 +03:00
|
|
|
],
|
|
|
|
}
|
|
|
|
|
2022-03-01 22:32:55 +03:00
|
|
|
const config = [check, type, transpile, locales]
|
2022-02-08 22:04:48 +03:00
|
|
|
export default config
|
|
|
|
|
|
|
|
function squelchTranspilationWarnings(warning: RollupWarning, warn: (warning: RollupWarning) => void) {
|
|
|
|
if (warning.pluginCode === 'TS5055') return
|
|
|
|
warn(warning)
|
2022-01-14 04:11:27 +03:00
|
|
|
}
|
|
|
|
|
2022-02-08 22:04:48 +03:00
|
|
|
function squelchTypeWarnings(warning: RollupWarning, warn: (warning: RollupWarning) => void) {
|
|
|
|
if (warning.code === 'UNUSED_EXTERNAL_IMPORT') return
|
|
|
|
warn(warning)
|
|
|
|
}
|