mirror of
https://github.com/jakejarvis/get-canonical-url.git
synced 2025-04-28 05:50:30 -04:00
switch to microbundle
This commit is contained in:
parent
5b3ea19ec0
commit
625837697b
@ -1,21 +1,16 @@
|
|||||||
{
|
{
|
||||||
"extends": [
|
"extends": [
|
||||||
"@jakejarvis/eslint-config",
|
"@jakejarvis/eslint-config",
|
||||||
"plugin:compat/recommended",
|
"plugin:@typescript-eslint/recommended"
|
||||||
"plugin:import/recommended"
|
|
||||||
],
|
],
|
||||||
"parser": "@babel/eslint-parser",
|
"plugins": [
|
||||||
"parserOptions": {
|
"@typescript-eslint"
|
||||||
"sourceType": "module",
|
],
|
||||||
"requireConfigFile": false
|
"parser": "@typescript-eslint/parser",
|
||||||
},
|
|
||||||
"env": {
|
"env": {
|
||||||
"es6": true,
|
"browser": true
|
||||||
"browser": true,
|
|
||||||
"node": false
|
|
||||||
},
|
},
|
||||||
"ignorePatterns": [
|
"ignorePatterns": [
|
||||||
"*.d.ts",
|
|
||||||
"dist/**"
|
"dist/**"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -9,11 +9,13 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: '14.x'
|
node-version: 16.x
|
||||||
|
cache: yarn
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- run: yarn build
|
- run: yarn build
|
||||||
- run: yarn test
|
- run: yarn test
|
||||||
|
9
.github/workflows/release.yml
vendored
9
.github/workflows/release.yml
vendored
@ -13,10 +13,9 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 14
|
node-version: 16.x
|
||||||
registry-url: https://registry.npmjs.org/
|
registry-url: https://registry.npmjs.org/
|
||||||
- env:
|
- run: yarn install --frozen-lockfile
|
||||||
|
- run: yarn publish
|
||||||
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
run: |
|
|
||||||
yarn install --frozen-lockfile
|
|
||||||
yarn publish
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
# 🔗 get-canonical-url
|
# 🔗 get-canonical-url
|
||||||
|
|
||||||
[](https://github.com/jakejarvis/get-canonical-url/actions/workflows/ci.yml)
|
[](https://github.com/jakejarvis/get-canonical-url/actions/workflows/ci.yml)
|
||||||
[](https://www.npmjs.com/package/get-canonical-url)
|
[](https://www.npmjs.com/package/get-canonical-url)
|
||||||
[](LICENSE)
|
|
||||||
|
|
||||||
Determines the current page's canonical URL and optionally normalizes it via [normalize-url](https://github.com/sindresorhus/normalize-url) for consistency.
|
Determines the current page's canonical URL and optionally normalizes it via [normalize-url](https://github.com/sindresorhus/normalize-url) for consistency.
|
||||||
|
|
||||||
@ -14,6 +13,12 @@ npm install get-canonical-url
|
|||||||
yarn add get-canonical-url
|
yarn add get-canonical-url
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or pull directly from [unpkg](https://unpkg.com/browse/get-canonical-url/) in-browser:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="https://unpkg.com/get-canonical-url/dist/get-canonical-url.min.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### With `<link rel="canonical">`
|
### With `<link rel="canonical">`
|
||||||
|
47
package.json
47
package.json
@ -3,64 +3,47 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"description": "🔗 Determines the current page's canonical URL and optionally normalizes it for consistency.",
|
"description": "🔗 Determines the current page's canonical URL and optionally normalizes it for consistency.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://github.com/jakejarvis/get-canonical-url",
|
"repository": "jakejarvis/get-canonical-url",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Jake Jarvis",
|
"name": "Jake Jarvis",
|
||||||
"email": "jake@jarv.is",
|
"email": "jake@jarv.is",
|
||||||
"url": "https://jarv.is/"
|
"url": "https://jarv.is/"
|
||||||
},
|
},
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/jakejarvis/get-canonical-url.git"
|
|
||||||
},
|
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"main": "./dist/get-canonical-url.cjs.js",
|
"source": "./src/get-canonical-url.ts",
|
||||||
|
"main": "./dist/get-canonical-url.cjs",
|
||||||
"module": "./dist/get-canonical-url.esm.js",
|
"module": "./dist/get-canonical-url.esm.js",
|
||||||
"unpkg": "./dist/get-canonical-url.min.js",
|
"unpkg": "./dist/get-canonical-url.min.js",
|
||||||
"types": "./dist/get-canonical-url.d.ts",
|
|
||||||
"exports": {
|
"exports": {
|
||||||
"require": "./dist/get-canonical-url.cjs.js",
|
"require": "./dist/get-canonical-url.cjs",
|
||||||
"import": "./dist/get-canonical-url.esm.js",
|
"import": "./dist/get-canonical-url.esm.js",
|
||||||
"browser": "./dist/get-canonical-url.min.js"
|
"browser": "./dist/get-canonical-url.min.js"
|
||||||
},
|
},
|
||||||
|
"types": "./dist/get-canonical-url.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rollup -c",
|
"build": "microbundle --format cjs,esm,umd --name 'canonicalUrl'",
|
||||||
"watch": "rollup -c -w",
|
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"prepublishOnly": "yarn build"
|
"prepublishOnly": "yarn build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {},
|
||||||
"normalize-url": "^7.0.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.15.8",
|
|
||||||
"@babel/eslint-parser": "^7.15.8",
|
|
||||||
"@babel/preset-env": "^7.15.8",
|
|
||||||
"@jakejarvis/eslint-config": "*",
|
"@jakejarvis/eslint-config": "*",
|
||||||
"@rollup/plugin-babel": "^5.3.0",
|
|
||||||
"@rollup/plugin-commonjs": "^21.0.0",
|
|
||||||
"@rollup/plugin-eslint": "^8.0.1",
|
|
||||||
"@rollup/plugin-node-resolve": "^13.0.5",
|
|
||||||
"@types/chai": "^4.2.22",
|
"@types/chai": "^4.2.22",
|
||||||
"@types/jsdom": "^16.2.13",
|
"@types/jsdom": "^16.2.13",
|
||||||
"@types/mocha": "^9.0.0",
|
"@types/mocha": "^9.0.0",
|
||||||
"builtin-modules": "^3.2.0",
|
"@typescript-eslint/eslint-plugin": "^5.3.1",
|
||||||
|
"@typescript-eslint/parser": "^5.3.1",
|
||||||
"chai": "^4.3.4",
|
"chai": "^4.3.4",
|
||||||
"eslint": "^8.0.0",
|
"eslint": "^8.2.0",
|
||||||
"eslint-plugin-compat": "~3.13.0",
|
"jsdom": "^18.0.1",
|
||||||
"eslint-plugin-import": "~2.25.2",
|
"microbundle": "^0.14.1",
|
||||||
"jsdom": "^18.0.0",
|
"mocha": "^9.1.3",
|
||||||
"mocha": "^9.1.2",
|
"normalize-url": "^7.0.2",
|
||||||
"rollup": "^2.58.0",
|
"typescript": "^4.4.4"
|
||||||
"rollup-plugin-copy": "^3.4.0",
|
|
||||||
"rollup-plugin-delete": "^2.0.0",
|
|
||||||
"rollup-plugin-filesize": "^9.1.1",
|
|
||||||
"rollup-plugin-node-externals": "^2.2.0",
|
|
||||||
"rollup-plugin-terser": "^7.0.2"
|
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"url",
|
"url",
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
import pkg from "./package.json";
|
|
||||||
import resolve from "@rollup/plugin-node-resolve";
|
|
||||||
import externals from "rollup-plugin-node-externals";
|
|
||||||
import { babel } from "@rollup/plugin-babel";
|
|
||||||
import { terser } from "rollup-plugin-terser";
|
|
||||||
import filesize from "rollup-plugin-filesize";
|
|
||||||
import copy from "rollup-plugin-copy";
|
|
||||||
import del from "rollup-plugin-delete";
|
|
||||||
import commonjs from "@rollup/plugin-commonjs";
|
|
||||||
import eslint from "@rollup/plugin-eslint";
|
|
||||||
|
|
||||||
const exportName = "canonicalUrl";
|
|
||||||
const input = "src/index.js";
|
|
||||||
const banner = `/*! ${pkg.name} v${pkg.version} | ${pkg.license} License | ${pkg.homepage} */`;
|
|
||||||
|
|
||||||
export default [
|
|
||||||
{
|
|
||||||
// universal (browser and node)
|
|
||||||
input,
|
|
||||||
output: [
|
|
||||||
{
|
|
||||||
name: exportName,
|
|
||||||
file: pkg.exports.browser.replace(".min.js", ".js"), // unminified (.js)
|
|
||||||
format: "umd",
|
|
||||||
exports: "default",
|
|
||||||
esModule: false,
|
|
||||||
banner,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: exportName,
|
|
||||||
file: pkg.exports.browser, // minified (.min.js)
|
|
||||||
format: "umd",
|
|
||||||
exports: "default",
|
|
||||||
esModule: false,
|
|
||||||
plugins: [
|
|
||||||
terser({
|
|
||||||
format: {
|
|
||||||
preamble: banner,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
del({ targets: "dist/*" }),
|
|
||||||
eslint(),
|
|
||||||
resolve(),
|
|
||||||
commonjs(),
|
|
||||||
babel({
|
|
||||||
babelHelpers: "bundled",
|
|
||||||
presets: [["@babel/preset-env"]],
|
|
||||||
exclude: ["node_modules/**"],
|
|
||||||
}),
|
|
||||||
copy({
|
|
||||||
// clearly this isn't really typescript, so we need to manually copy the type definition file
|
|
||||||
targets: [
|
|
||||||
{
|
|
||||||
src: input.replace(".js", ".d.ts"),
|
|
||||||
dest: "dist",
|
|
||||||
rename: pkg.types.replace("./dist/", ""),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
filesize(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// modules
|
|
||||||
input,
|
|
||||||
output: [
|
|
||||||
{
|
|
||||||
// ES6 module (import)
|
|
||||||
file: pkg.exports.import,
|
|
||||||
format: "esm",
|
|
||||||
exports: "named",
|
|
||||||
banner: banner,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// commonjs (require)
|
|
||||||
file: pkg.exports.require,
|
|
||||||
format: "cjs",
|
|
||||||
exports: "named",
|
|
||||||
banner: banner,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
external: ["normalize-url"],
|
|
||||||
plugins: [
|
|
||||||
externals({ deps: true }),
|
|
||||||
commonjs(),
|
|
||||||
babel({
|
|
||||||
babelHelpers: "bundled",
|
|
||||||
exclude: ["node_modules/**"],
|
|
||||||
}),
|
|
||||||
filesize(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
80
src/get-canonical-url.ts
Normal file
80
src/get-canonical-url.ts
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*! get-canonical-url | MIT | https://github.com/jakejarvis/get-canonical-url */
|
||||||
|
import normalizeUrl from "normalize-url";
|
||||||
|
import type { Options as NormalizeOptions } from "normalize-url";
|
||||||
|
|
||||||
|
export interface Options {
|
||||||
|
/**
|
||||||
|
* Clean-up and normalize the determined canonical URL.
|
||||||
|
*
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
readonly normalize?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options passed directly to [`normalize-url`](https://github.com/sindresorhus/normalize-url#options).
|
||||||
|
*
|
||||||
|
* Requires `options.normalize = true`.
|
||||||
|
*
|
||||||
|
* @default { stripWWW: false, stripHash: true, removeQueryParameters: true, removeTrailingSlash: false }
|
||||||
|
*/
|
||||||
|
readonly normalizeOptions?: NormalizeOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make an educated guess using other clues if canonical isn't explicitly set in the page's `<head>`.
|
||||||
|
*
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
readonly guess?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current page's canonical URL.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```
|
||||||
|
* // This imaginary page's <head> contains the following link tag:
|
||||||
|
* // <link rel="canonical" href="https://www.example.com/" />
|
||||||
|
*
|
||||||
|
* import canonicalUrl from "get-canonical-url";
|
||||||
|
*
|
||||||
|
* canonicalUrl();
|
||||||
|
* //=> 'https://www.example.com/'
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export default function canonicalUrl(options: Options = {}): string | undefined {
|
||||||
|
options = {
|
||||||
|
normalize: false,
|
||||||
|
normalizeOptions: {
|
||||||
|
// A few sensible normalize-url defaults:
|
||||||
|
// https://github.com/sindresorhus/normalize-url#options
|
||||||
|
stripWWW: false,
|
||||||
|
stripHash: true,
|
||||||
|
removeQueryParameters: true,
|
||||||
|
removeTrailingSlash: false,
|
||||||
|
},
|
||||||
|
guess: false,
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start with a blank slate
|
||||||
|
let url: string | undefined = undefined;
|
||||||
|
|
||||||
|
// Look for a <link rel="canonical"> tag in the page's <head>
|
||||||
|
const linkElement: HTMLLinkElement | null = document.head.querySelector("link[rel='canonical']");
|
||||||
|
|
||||||
|
if (linkElement !== null) {
|
||||||
|
// Easy peasy, there was a <link rel="canonical"> tag!
|
||||||
|
url = linkElement.href;
|
||||||
|
} else if (options.guess) {
|
||||||
|
// We've been told to make an educated guess if canonical isn't explicitly set
|
||||||
|
url = document.documentURI || document.URL || window.location.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url && options.normalize) {
|
||||||
|
// Pass either custom options or defaults (above) directly to normalize-url
|
||||||
|
url = normalizeUrl(url, options.normalizeOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some sort of URL has been determined by this point, unless it's impossible
|
||||||
|
return url;
|
||||||
|
}
|
42
src/index.d.ts
vendored
42
src/index.d.ts
vendored
@ -1,42 +0,0 @@
|
|||||||
import type { Options as NormalizeOptions } from "normalize-url";
|
|
||||||
|
|
||||||
export interface Options {
|
|
||||||
/**
|
|
||||||
* Clean-up and normalize the determined canonical URL.
|
|
||||||
*
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
readonly normalize?: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options passed directly to [`normalize-url`](https://github.com/sindresorhus/normalize-url#options).
|
|
||||||
*
|
|
||||||
* Requires `options.normalize = true`.
|
|
||||||
*
|
|
||||||
* @default { stripWWW: false, stripHash: true, removeQueryParameters: true, removeTrailingSlash: false }
|
|
||||||
*/
|
|
||||||
readonly normalizeOptions?: NormalizeOptions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make an educated guess using other clues if canonical isn't explicitly set in the page's `<head>`.
|
|
||||||
*
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
readonly guess?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current page's canonical URL.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* // This imaginary page's <head> contains the following link tag:
|
|
||||||
* // <link rel="canonical" href="https://www.example.com/" />
|
|
||||||
*
|
|
||||||
* import canonicalUrl from "get-canonical-url";
|
|
||||||
*
|
|
||||||
* canonicalUrl();
|
|
||||||
* //=> 'https://www.example.com/'
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export default function canonicalUrl(options?: Options): string | undefined;
|
|
39
src/index.js
39
src/index.js
@ -1,39 +0,0 @@
|
|||||||
import normalizeUrl from "normalize-url";
|
|
||||||
|
|
||||||
export default function canonicalUrl(options = {}) {
|
|
||||||
options = {
|
|
||||||
normalize: false,
|
|
||||||
normalizeOptions: {
|
|
||||||
// A few sensible normalize-url defaults:
|
|
||||||
// https://github.com/sindresorhus/normalize-url#options
|
|
||||||
stripWWW: false,
|
|
||||||
stripHash: true,
|
|
||||||
removeQueryParameters: true,
|
|
||||||
removeTrailingSlash: false,
|
|
||||||
},
|
|
||||||
guess: false,
|
|
||||||
...options,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Start with a blank slate
|
|
||||||
let url = undefined;
|
|
||||||
|
|
||||||
// Look for a <link rel="canonical"> tag in the page's <head>
|
|
||||||
const linkElement = document.head.querySelector("link[rel='canonical']");
|
|
||||||
|
|
||||||
if (linkElement !== null) {
|
|
||||||
// Easy peasy, there was a <link rel="canonical"> tag!
|
|
||||||
url = linkElement.href;
|
|
||||||
} else if (options.guess) {
|
|
||||||
// We've been told to make an educated guess if canonical isn't explicitly set
|
|
||||||
url = document.documentURI || document.URL || window.location.href;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.normalize) {
|
|
||||||
// Pass either custom options or defaults (above) directly to normalize-url
|
|
||||||
url = normalizeUrl(url, options.normalizeOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some sort of URL has been determined by this point, unless it's impossible
|
|
||||||
return url;
|
|
||||||
}
|
|
@ -68,7 +68,6 @@ describe("without canonical tag", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function wait(ms) {
|
async function wait(ms) {
|
||||||
// eslint-disable-next-line compat/compat
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
setTimeout(resolve, ms);
|
setTimeout(resolve, ms);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user