build: Yarn v2 and ESM & CJS bundles (#114)

This commit is contained in:
Arthur Fiorette 2022-01-13 18:57:50 -03:00 committed by GitHub
parent be9d7357b5
commit 4734c5f7a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 10996 additions and 6015 deletions

View File

@ -2,4 +2,7 @@
/dist
/types
/ignore
/docs
/docs
/esm
/cjs
/umd

View File

@ -22,7 +22,7 @@ jobs:
cache: 'yarn'
- name: Install packages
run: yarn --prefer-offline
run: yarn install
- name: Lint
run: yarn lint
@ -34,7 +34,7 @@ jobs:
run: yarn build
- name: ESCheck
run: yarn escheck
run: yarn check
- name: Publish to Codecov
uses: codecov/codecov-action@v2.1.0

View File

@ -37,7 +37,7 @@ jobs:
cache: 'yarn'
- name: Install packages
run: yarn --prefer-offline
run: yarn install
- name: Build
run: yarn build

View File

@ -24,7 +24,7 @@ jobs:
cache: 'yarn'
- name: Install packages
run: yarn --prefer-offline
run: yarn install
- name: Build
run: npm run build

23
.gitignore vendored
View File

@ -1,10 +1,21 @@
# Javascript
coverage
node_modules
/umd
/cjs
/esm
dist
types
ignore
.vscode/settings.json
package-lock.json
coverage
# Random
/ignore
*.log
# Vscode
.vscode/*
!.vscode/launch.json
# Npm & Yarn
package-lock.json
.yarn/*
!.yarn/releases
!.yarn/plugins

View File

@ -8,6 +8,8 @@
!package.json
!tsconfig*.json
!/src/**
!/dist/**
!/umd/**
!/cjs/**
!/esm/**
!/examples/**

View File

@ -3,8 +3,13 @@ node_modules
/ignore
/coverage
/dist
/umd
/cjs
/esm
/types
/tsconfig.json
.yarn
changelog.md
CHANGELOG.md

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

768
.yarn/releases/yarn-3.1.1.cjs vendored Executable file

File diff suppressed because one or more lines are too long

View File

@ -1,2 +0,0 @@
version-git-message "tag: v%s"
version-git-tag true

11
.yarnrc.yml Normal file
View File

@ -0,0 +1,11 @@
enableGlobalCache: true
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-version.cjs
spec: '@yarnpkg/plugin-version'
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: '@yarnpkg/plugin-interactive-tools'
yarnPath: .yarn/releases/yarn-3.1.1.cjs

18
build/build.sh Normal file
View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
# This script is used to build the project.
# It is intended to be run from the project's root directory.
echo "\nStarting build...\n"
rm -rf cjs/ esm/ umd/
echo "Target cleared...\n"
webpack --config build/webpack.config.js &
tsc -p build/tsconfig.cjs.json &
tsc -p build/tsconfig.esm.json &
wait
echo "\nBuild done!"

13
build/check.sh Normal file
View File

@ -0,0 +1,13 @@
#!/usr/bin/env bash
# This script is used to check the umd's ecmascript compatibility.
# It is intended to be run from the project's root directory.
echo "\nStarting checking...\n"
es-check es5 umd/es5.min.js &
es-check es6 umd/es6.min.js &
wait
echo "\nCheck done!"

9
build/tsconfig.cjs.json Normal file
View File

@ -0,0 +1,9 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"module": "CommonJS",
"target": "ES2017",
"outDir": "../cjs"
},
"include": ["../src"]
}

9
build/tsconfig.esm.json Normal file
View File

@ -0,0 +1,9 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"target": "ES2017",
"outDir": "../esm"
},
"include": ["../src"]
}

13
build/tsconfig.umd.json Normal file
View File

@ -0,0 +1,13 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"module": "ESNext", // webpack converts to UMD
"target": "ESNext",
"outDir": "../umd",
// No declaration
"declaration": false,
"declarationMap": false
},
"include": ["../src"]
}

75
build/webpack.config.js Normal file
View File

@ -0,0 +1,75 @@
//@ts-check
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const TerserWebpackPlugin = require('terser-webpack-plugin');
const root = (...p) => path.resolve(__dirname, '..', ...p);
/**
* @param {{
* output: string;
* entry: string;
* esTarget: string;
* }} options
* @returns {import('webpack').Configuration}
*/
const config = ({ output, esTarget, entry }) => ({
mode: 'production',
entry: root('src', entry),
output: {
path: root(),
globalObject: `typeof self === 'undefined' ? this : self`,
filename: output + '.js',
sourceMapFilename: output + '.map',
library: {
type: 'umd',
name: 'AxiosCacheInterceptor'
},
chunkFormat: 'module'
},
target: esTarget,
resolve: {
extensions: ['.ts', '.js']
},
devtool: 'source-map',
module: {
rules: [
{
include: root('src'),
test: /\.(ts|js)$/,
loader: 'ts-loader',
options: {
configFile: root('build', 'tsconfig.umd.json'),
compilerOptions: {
target: esTarget
}
}
}
]
},
optimization: {
minimize: true,
minimizer: [new TerserWebpackPlugin({ parallel: true })]
}
});
module.exports = [
config({
esTarget: 'es2015', //es6
entry: 'index.ts',
output: 'umd/es6.min'
}),
config({
esTarget: 'es5',
entry: 'index.ts',
output: 'umd/es5.min'
})
];

1
docs/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/.yarn

View File

@ -2,27 +2,23 @@
## CommonJS
The code is compiled with `webpack` for ES2017+.
The code compiled with `CommonJS` is for ES2017+.
- `axios-cache-interceptor`: Redirects to `/dist/index.js`
- `axios-cache-interceptor/dist/index.js`: The main library file.
- `axios-cache-interceptor/dist/index.d.ts`: The Typescript definition file.
Every browser build is also compatible with CommonsJS because it builds with UMD, so you
can use them too.
```js
import { setupCache } from 'axios-cache-interceptor'; // (Default is CJS)
import { setupCache } from 'axios-cache-interceptor/cjs';
```
## UMD
> _NOTE_: Axios itself requires [ES6 Promises](https://axios-http.com/docs/notes#promises)
The UMD code is compiled with `webpack` with support to `>= ES5`. See the
[build config](/webpack.config.js). You can import these files anywhere (Browser,
CommonsJS and more)
The UMD code is compiled with `webpack` to support `>= ES5`. See the
[build config](build/webpack.config.js). You can import these files anywhere (Browser,
CommonsJS, ESM and more)
- `axios-cache-interceptor/dist/index.min.js`: Production file for ES6+
- `axios-cache-interceptor/dist/index.es5.min.js`: Production file for ES5+
- `axios-cache-interceptor/dist/index.es2020.min.js`: Production file for ES2020+
- `axios-cache-interceptor/dist/index.development.js`: Development file (ES2020+)
- `axios-cache-interceptor/umd/es6.min.js`: Production file for ES6+
- `axios-cache-interceptor/umd/es5.min.js`: Production file for ES5+
```html
<!-- You can use the cdn of your choice -->
@ -38,3 +34,19 @@ CommonsJS and more)
<!-- Etc... -->
```
```js
import { setupCache } from 'axios-cache-interceptor/umd';
```
## ESModule
The code compiled with `ESModule` is for ES2017+.
This library exports its `ESM` code at `axios-cache-interceptor/esm`. It's useful to
enable _tree-shaking_ and other optimizations. You probably won't have to directly import
from this folder, instead, bundlers should do that for you.
```js
import { setupCache } from 'axios-cache-interceptor/esm';
```

View File

@ -26,8 +26,15 @@ yarn add axios axios-cache-interceptor
```
```js
// CommonJS
const { setupCache } = require('axios-cache-interceptor');
import { setupCache } from 'axios-cache-interceptor';
// ES Modules
import { setupCache } from 'axios-cache-interceptor/esm';
// Universal
const { setupCache } = require('axios-cache-interceptor/umd');
```
## With CDNs
@ -36,37 +43,19 @@ import { setupCache } from 'axios-cache-interceptor';
const { setupCache } = window.AxiosCacheInterceptor;
```
<!-- https://www.jsdelivr.com/package/npm/axios-cache-interceptor?path=dist -->
```html
<!-- Replace latest with the desired version -->
<!-- Development for ES2020+ (~30.0KB) -->
<script
src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@0.8.0/dist/index.development.js"
integrity="sha256-oEvQQcJv78S8QSJOY6XQ2uJ2dGwnnhAsYLDeXx0DHWA="
crossorigin="anonymous"
></script>
<!-- Production for ES6+ (~11.3KB) -->
<script
src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@0.8.0/dist/index.min.js"
integrity="sha256-vtHJnEYMjzfFDDPBAic56ppjVrN6ze2qi7wXM9a/BSM="
crossorigin="anonymous"
src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@0.8.1/umd/es6.min.js"
crossorigin
></script>
<!-- Production for ES5+ (~18.2KB) -->
<!-- Production for ES5+ (~18.2KB) (Needs polyfill) -->
<script
src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@0.8.0/dist/index.es5.min.js"
integrity="sha256-R/q1PnksvXhveo9qidplrGvGGsmFDAsal9M6bUfnNS4="
crossorigin="anonymous"
></script>
<!-- Production for ES2020+ (~9.2KB) -->
<script
src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@0.8.0/dist/index.es2020.min.js"
integrity="sha256-amiYeGe9088KbQ+4xF0/9tNP+ks4Ze5LF6cZ7aiow3Q="
crossorigin="anonymous"
src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@0.8.1/umd/es5.min.js"
crossorigin
></script>
```
@ -75,7 +64,11 @@ const { setupCache } = window.AxiosCacheInterceptor;
You can import any [CDN Url](#with-cdns) and use it in your code. **UMD Compatible**
```js
import { setupCache } from 'https://cdn.jsdelivr.net/npm/axios-cache-interceptor@0.8.0/dist/index.es2020.min.js';
// ESM with Skypack CDN (Preferred!)
import { setupCache } from 'https://cdn.skypack.dev/axios-cache-interceptor@0.8.1?dts';
// UMD bundled code
import { setupCache } from 'https://cdn.jsdelivr.net/npm/axios-cache-interceptor@0.8.1/umd/index.min.js';
```
## Support List

View File

@ -18,3 +18,4 @@ even needing one of those fat javascript libraries for state management.
- [x] Infinity storage options
- [x] Cache revalidation from responses
- [x] Support for external storages
- [x] ESM, CJS and UMD support

File diff suppressed because it is too large Load Diff

View File

@ -4,5 +4,11 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src', '<rootDir>/test']
roots: ['<rootDir>/src', '<rootDir>/test'],
globals: {
'ts-jest': {
isolatedModules: true,
useESM: true
}
}
};

View File

@ -2,16 +2,22 @@
"name": "axios-cache-interceptor",
"version": "0.8.0",
"description": "Cache interceptor for axios",
"types": "./dist/index.ts",
"main": "./dist/index.js",
"browser": "./dist/index.min.js",
"jsdelivr": "./dist/index.min.js",
"unpkg": "./dist/index.min.js",
"main": "./cjs/index.js",
"types": "./cjs/index.d.ts",
"module": "./esm/index.js",
"exports": {
"import": "./esm/index.js",
"require": "./cjs/index.js",
"default": "./umd/es6.min.js"
},
"browser": "./umd/es6.min.js",
"jsdelivr": "./umd/es6.min.js",
"unpkg": "./umd/es6.min.js",
"runkitExampleFilename": "./examples/runkit.js",
"scripts": {
"build": "webpack",
"build": "sh build/build.sh",
"test": "jest --coverage",
"escheck": "es-check es5 ./dist/index.es5.min.js && es-check es6 ./dist/index.min.js",
"check": "sh build/check.sh",
"format": "prettier --write .",
"lint": "eslint . --ext .ts",
"version": "auto-changelog -p && git add CHANGELOG.md"
@ -48,25 +54,25 @@
},
"devDependencies": {
"@arthurfiorette/prettier-config": "*",
"@types/jest": "^27.0.2",
"@types/node": "^17.0.0",
"@types/jest": "^27.4.0",
"@types/node": "^17.0.8",
"@types/webpack": "^5.28.0",
"@typescript-eslint/eslint-plugin": "^5.9.1",
"@typescript-eslint/parser": "^5.9.1",
"auto-changelog": "^2.3.0",
"axios": "~0.24.0",
"es-check": "^6.1.1",
"eslint": "^8.3.0",
"eslint": "^8.6.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^27.4.5",
"prettier": "^2.3.2",
"prettier-plugin-jsdoc": "^0.3.23",
"prettier-plugin-organize-imports": "^2.3.3",
"ts-jest": "^27.1.1",
"jest": "^27.4.7",
"prettier": "^2.5.1",
"prettier-plugin-jsdoc": "^0.3.30",
"prettier-plugin-organize-imports": "^2.3.4",
"ts-jest": "^27.1.2",
"ts-loader": "^9.2.6",
"typescript": "^4.5.4",
"webpack": "^5.65.0",
"webpack": "^5.66.0",
"webpack-cli": "^4.9.1"
},
"peerDependencies": {

2
src/cache/create.ts vendored
View File

@ -44,7 +44,7 @@ export type CacheOptions = Partial<CacheInstance> & Partial<CacheProperties>;
*
* @param axios The already created axios instance
* @param config The config for the caching interceptors
* @returns The same instance with better typescript types.
* @returns The same instance with extended typescript types.
*/
export function setupCache(
axios: AxiosInstance,

View File

@ -1,5 +0,0 @@
export * from './index';
console.warn(
'You are using a development build. Make sure to use the correct build in production\nhttps://axios-cache-interceptor.js.org/#/pages/installing'
);

View File

@ -93,15 +93,16 @@ export function defaultRequestInterceptor(axios: AxiosCacheInstance) {
//Even though the response interceptor receives this one from here,
// it has been configured to ignore cached responses = true
// eslint-disable-next-line @typescript-eslint/require-await
config.adapter = async (): Promise<CacheAxiosResponse<unknown, unknown>> => ({
config,
data: cachedResponse.data,
headers: cachedResponse.headers,
status: cachedResponse.status,
statusText: cachedResponse.statusText,
cached: true,
id: key
});
config.adapter = (): Promise<CacheAxiosResponse<unknown, unknown>> =>
Promise.resolve({
config,
data: cachedResponse.data,
headers: cachedResponse.headers,
status: cachedResponse.status,
statusText: cachedResponse.statusText,
cached: true,
id: key
});
return config;
};

View File

@ -27,8 +27,12 @@ export function buildMemoryStorage() {
const data: Record<string, StorageValue> = {};
const storage = buildStorage({
find: (key) => data[key],
set: (key, value) => void (data[key] = value),
remove: (key) => void delete data[key]
set: (key, value) => {
data[key] = value;
},
remove: (key) => {
delete data[key];
}
});
return { ...storage, data };
}

View File

@ -16,6 +16,9 @@ import { buildStorage } from './build';
* const myStorage = new Storage();
* const fromMyStorage = buildWebStorage(myStorage);
* ```
*
* @param prefix The prefix to index the storage. Useful to prevent collision between
* multiple places using the same storage.
*/
export function buildWebStorage(storage: Storage, prefix = '') {
return buildStorage({
@ -23,7 +26,11 @@ export function buildWebStorage(storage: Storage, prefix = '') {
const json = storage.getItem(prefix + key);
return json ? (JSON.parse(json) as StorageValue) : undefined;
},
set: (key, value) => void storage.setItem(prefix + key, JSON.stringify(value)),
remove: (key) => void storage.removeItem(prefix + key)
set: (key, value) => {
storage.setItem(prefix + key, JSON.stringify(value));
},
remove: (key) => {
storage.removeItem(prefix + key);
}
});
}

View File

@ -25,7 +25,7 @@ export const defaultKeyGenerator: KeyGenerator = ({
// complete url
baseURL + (baseURL && url ? '/' : '') + url
}::${
//params
// params
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
params ? JSON.stringify(params, Object.keys(params).sort()) : '{}'
}`;

View File

@ -30,8 +30,10 @@ export async function updateCache<T, D>(
continue;
}
if (newValue !== 'ignore') {
await storage.set(cacheKey, newValue);
if (newValue === 'ignore') {
continue;
}
await storage.set(cacheKey, newValue);
}
}

View File

@ -1,20 +0,0 @@
import { setupCache } from '../src/cache/create';
import { buildMemoryStorage } from '../src/storage/memory';
import { buildWebStorage } from '../src/storage/web-api';
describe('test bundle imports', () => {
it('test development bundle imports', async () => {
const oldWarn = console.warn;
console.warn = jest.fn();
const bundle = await import('../src/index.development');
expect(console.warn).toHaveBeenCalledTimes(1);
expect(bundle.setupCache).toBe(setupCache);
expect(bundle.buildMemoryStorage).toBe(buildMemoryStorage);
expect(bundle.buildWebStorage).toBe(buildWebStorage);
console.warn = oldWarn;
});
});

View File

@ -1,8 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"declaration": false,
"declarationMap": false
},
"include": ["src"]
}

View File

@ -1,105 +0,0 @@
//@ts-check
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const TerserWebpackPlugin = require('terser-webpack-plugin');
/**
* @param {{
* output: string;
* entry: string;
* esTarget: string;
* minimize: boolean;
* override?: import('typescript').CompilerOptions;
* library?: import('webpack').LibraryOptions;
* }} options
* @returns {import('webpack').Configuration}
*/
const config = ({ output, esTarget, minimize, entry, override = {}, library }) => ({
mode: 'production',
entry: path.resolve(__dirname, 'src', entry),
output: {
path: path.resolve(__dirname, 'dist'),
globalObject: `typeof self == 'undefined' ? this : self`,
filename: output,
library: {
type: 'umd',
name: 'AxiosCacheInterceptor',
...library
},
chunkFormat: 'module'
},
target: esTarget,
resolve: {
extensions: ['.ts', '.js']
},
devtool: 'source-map',
module: {
rules: [
{
include: path.resolve(__dirname, 'src'),
test: /\.(ts|js)$/,
loader: 'ts-loader',
options: {
configFile: path.resolve(__dirname, 'tsconfig.build.json'),
compilerOptions: {
target: esTarget,
...override
}
}
}
]
},
optimization: {
minimize,
minimizer: [new TerserWebpackPlugin({ parallel: true })]
}
});
module.exports = [
config({
esTarget: 'es2020',
entry: 'index.development.ts',
output: 'index.development.js',
minimize: false
}),
config({
esTarget: 'es2015', // ES6
entry: 'index.ts',
output: 'index.min.js',
minimize: true
}),
config({
esTarget: 'es5',
entry: 'index.ts',
output: 'index.es5.min.js',
minimize: true
}),
config({
esTarget: 'es2020',
entry: 'index.ts',
output: 'index.es2020.min.js',
minimize: true
}),
config({
esTarget: 'es2017',
entry: 'index.ts',
output: 'index.js',
minimize: true,
library: {
type: 'commonjs',
name: undefined
},
override: {
declaration: true,
declarationMap: true
}
})
];

10990
yarn.lock

File diff suppressed because it is too large Load Diff