Compare commits

...

10 Commits

Author SHA1 Message Date
github-actions[bot]
bcf8f4fe83 Version Packages 2021-06-21 16:25:40 +02:00
Thomas Allmer
5330740cb3 fix(cli): replace images to be responsive from the bottom up 2021-06-21 16:20:48 +02:00
Thomas Allmer
2edd61beaa chore: remove image hashes from tests 2021-06-21 15:56:41 +02:00
github-actions[bot]
2a5fc08f35 Version Packages 2021-06-21 14:37:07 +02:00
Thomas Allmer
43a7ca10c3 fix(cli): responsive images need to respect pathPrefix 2021-06-21 14:35:51 +02:00
github-actions[bot]
da39fa72f3 Version Packages 2021-06-16 09:08:08 +02:00
Thomas Allmer
a0e8edfbb9 fix(check-html-links): ignore not http schema urls 2021-06-16 09:04:05 +02:00
Thomas Allmer
50434293bb fix(check-html-links): ignore tel links 2021-06-16 09:04:05 +02:00
Thomas Allmer
f08f92615b fix(check-html-links): add missing slash dependency 2021-06-16 09:04:05 +02:00
Thomas Allmer
1949b1e1cb fix(check-html-links): ignore html encoded mailto links 2021-06-16 09:04:05 +02:00
18 changed files with 194 additions and 34 deletions

View File

@@ -1,5 +1,31 @@
# check-html-links # check-html-links
## 0.2.3
### Patch Changes
- 5043429: Ignore `<a href="tel:9999">` links
- f08f926: Add missing `slash` dependency
- a0e8edf: Ignore links containing not http schema urls like `sketch://`, `vscode://`, ...
```html
<a href="sketch://add-library?url=https%3A%2F%2Fmyexample.com%2Fdesign%2Fui-kit.xml"></a>
<a href="vscode://file/c:/myProject/package.json:5:10"></a>
```
- 1949b1e: Ignore plain and html encoded mailto links
```html
<!-- source -->
<a href="mailto:address@example.com">contact</a>
<!-- html encoded -->
<a
href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#97;&#100;&#100;&#114;&#101;&#115;&#115;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;"
>contact</a
>
```
## 0.2.2 ## 0.2.2
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "check-html-links", "name": "check-html-links",
"version": "0.2.2", "version": "0.2.3",
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
@@ -37,7 +37,8 @@
"command-line-args": "^5.1.1", "command-line-args": "^5.1.1",
"glob": "^7.0.0", "glob": "^7.0.0",
"minimatch": "^3.0.4", "minimatch": "^3.0.4",
"sax-wasm": "^2.0.0" "sax-wasm": "^2.0.0",
"slash": "^3.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/glob": "^7.0.0" "@types/glob": "^7.0.0"

View File

@@ -182,6 +182,18 @@ function getValueAndAnchor(inValue) {
}; };
} }
/**
* @param {string} url
* @returns {boolean}
*/
function isNonHttpSchema(url) {
const found = url.match(/([a-z]+):/);
if (found) {
return found.length > 0;
}
return false;
}
/** /**
* *
* @param {Link[]} links * @param {Link[]} links
@@ -207,8 +219,13 @@ async function resolveLinks(links, { htmlFilePath, rootDir, ignoreUsage }) {
if (ignoreUsage(value)) { if (ignoreUsage(value)) {
// ignore // ignore
} else if (value.includes('mailto:')) { } else if (
value.startsWith('mailto:') ||
value.startsWith('&#109;&#97;&#105;&#108;&#116;&#111;&#58;') // = "mailto:" but html encoded
) {
// ignore for now - could add a check to validate if the email address is valid // ignore for now - could add a check to validate if the email address is valid
} else if (value.startsWith('tel:')) {
// ignore for now - could add a check to validate if the phone number is valid
} else if (valueFile === '' && anchor !== '') { } else if (valueFile === '' && anchor !== '') {
addLocalFile(htmlFilePath, anchor, usageObj); addLocalFile(htmlFilePath, anchor, usageObj);
} else if (value.startsWith('//') || value.startsWith('http')) { } else if (value.startsWith('//') || value.startsWith('http')) {
@@ -219,6 +236,8 @@ async function resolveLinks(links, { htmlFilePath, rootDir, ignoreUsage }) {
addLocalFile(filePath, anchor, usageObj); addLocalFile(filePath, anchor, usageObj);
} else if (value === '' && anchor === '') { } else if (value === '' && anchor === '') {
// no need to check it // no need to check it
} else if (isNonHttpSchema(value)) {
// not a schema we handle
} else { } else {
const filePath = path.join(path.dirname(htmlFilePath), valueFile); const filePath = path.join(path.dirname(htmlFilePath), valueFile);
addLocalFile(filePath, anchor, usageObj); addLocalFile(filePath, anchor, usageObj);

View File

@@ -1 +1,3 @@
<a href="mailto:foo@bar.com"></a> <a href="mailto:foo@bar.com"></a>
<!-- encoded mailto links -->
<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#97;&#100;&#100;&#114;&#101;&#115;&#115;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;"></a>

View File

@@ -0,0 +1,2 @@
<a href="sketch://add-library?url=https%3A%2F%2Fmyexample.com%2Fdesign%2Fui-kit.xml"></a>
<a href="vscode://file/c:/myProject/package.json:5:10"></a>

View File

@@ -0,0 +1 @@
<a href="tel:99999"></a>

View File

@@ -183,6 +183,16 @@ describe('validateFolder', () => {
expect(cleanup(errors)).to.deep.equal([]); expect(cleanup(errors)).to.deep.equal([]);
}); });
it('ignores tel links', async () => {
const { errors, cleanup } = await execute('fixtures/tel');
expect(cleanup(errors)).to.deep.equal([]);
});
it('ignore not http schema urls', async () => {
const { errors, cleanup } = await execute('fixtures/not-http-schema');
expect(cleanup(errors)).to.deep.equal([]);
});
it('ignoring a folder', async () => { it('ignoring a folder', async () => {
const { errors, cleanup } = await execute('fixtures/internal-link-ignore', { const { errors, cleanup } = await execute('fixtures/internal-link-ignore', {
ignoreLinkPatterns: ['./relative/*', './relative/**/*'], ignoreLinkPatterns: ['./relative/*', './relative/**/*'],

View File

@@ -1,5 +1,17 @@
# @rocket/cli # @rocket/cli
## 0.9.2
### Patch Changes
- 5330740: When replacing images with responsive picture tags do this from the bottom up so the initial dom parsing locations still hold true.
## 0.9.1
### Patch Changes
- 43a7ca1: Responsive images need to respect a set pathPrefix
## 0.9.0 ## 0.9.0
### Minor Changes ### Minor Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@rocket/cli", "name": "@rocket/cli",
"version": "0.9.0", "version": "0.9.2",
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
@@ -67,7 +67,7 @@
"@web/dev-server": "^0.1.4", "@web/dev-server": "^0.1.4",
"@web/dev-server-rollup": "^0.3.2", "@web/dev-server-rollup": "^0.3.2",
"@web/rollup-plugin-copy": "^0.2.0", "@web/rollup-plugin-copy": "^0.2.0",
"check-html-links": "^0.2.2", "check-html-links": "^0.2.3",
"command-line-args": "^5.1.1", "command-line-args": "^5.1.1",
"command-line-usage": "^6.1.1", "command-line-usage": "^6.1.1",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",

View File

@@ -2,6 +2,7 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const EleventyImage = require('@11ty/eleventy-img'); const EleventyImage = require('@11ty/eleventy-img');
const urlFilter = require('@11ty/eleventy/src/Filters/Url.js');
const { SaxEventType, SAXParser } = require('sax-wasm'); const { SaxEventType, SAXParser } = require('sax-wasm');
const { getComputedConfig } = require('../public/computedConfig.cjs'); const { getComputedConfig } = require('../public/computedConfig.cjs');
@@ -140,7 +141,7 @@ async function responsiveImages(images, { inputPath, outputDir, imagePresets = {
const metadata = await EleventyImage(filePath, { const metadata = await EleventyImage(filePath, {
outputDir: path.join(outputDir, 'images'), outputDir: path.join(outputDir, 'images'),
urlPath: '/images/', urlPath: urlFilter('/images/'),
...presetSettings, ...presetSettings,
}); });
const lowsrc = metadata.jpeg[0]; const lowsrc = metadata.jpeg[0];
@@ -194,7 +195,7 @@ async function responsiveImages(images, { inputPath, outputDir, imagePresets = {
function updateHtml(html, changes) { function updateHtml(html, changes) {
let newHtml = html; let newHtml = html;
for (const change of changes) { for (const change of changes.reverse()) {
newHtml = replaceBetween({ newHtml = replaceBetween({
html: newHtml, html: newHtml,
start: change.openStart, start: change.openStart,

View File

@@ -19,6 +19,7 @@ export function setFixtureDir(importMetaUrl) {
* @property {boolean} stripStartEndWhitespace * @property {boolean} stripStartEndWhitespace
* @property {boolean} stripScripts * @property {boolean} stripScripts
* @property {boolean} formatHtml * @property {boolean} formatHtml
* @property {boolean} replaceImageHashes
* @property {start|build} type * @property {start|build} type
*/ */
@@ -51,6 +52,7 @@ export async function readOutput(
stripScripts = false, stripScripts = false,
formatHtml = false, formatHtml = false,
type = 'build', type = 'build',
replaceImageHashes = false,
} = {}, } = {},
) { ) {
if (!cli || !cli.config) { if (!cli || !cli.config) {
@@ -70,6 +72,9 @@ export async function readOutput(
const scriptCloseTagStart = text.indexOf('</script>', scriptOpenTagEnd) + 9; const scriptCloseTagStart = text.indexOf('</script>', scriptOpenTagEnd) + 9;
text = text.substring(0, scriptOpenTagEnd) + text.substring(scriptCloseTagStart); text = text.substring(0, scriptOpenTagEnd) + text.substring(scriptCloseTagStart);
} }
if (replaceImageHashes) {
text = text.replace(/\/images\/([a-z0-9]+)-/g, '/images/__HASH__-');
}
if (formatHtml) { if (formatHtml) {
text = prettier.format(text, { parser: 'html', printWidth: 100 }); text = prettier.format(text, { parser: 'html', printWidth: 100 });
} }

View File

@@ -102,6 +102,30 @@ describe('RocketCli e2e', () => {
); );
const assetHtml = await readStartOutput(cli, 'use-assets/index.html'); const assetHtml = await readStartOutput(cli, 'use-assets/index.html');
expect(assetHtml).to.equal('<link rel="stylesheet" href="/_merged_assets/some.css">'); expect(assetHtml).to.equal('<link rel="stylesheet" href="/_merged_assets/some.css">');
const imageHtml = await readStartOutput(cli, 'image/index.html', { replaceImageHashes: true });
expect(imageHtml).to.equal(
[
'<p>',
' <figure>',
' <picture>',
'<source type="image/avif" srcset="/images/__HASH__-600.avif 600w, /images/__HASH__-900.avif 900w" sizes="100vw">',
'<source type="image/jpeg" srcset="/images/__HASH__-600.jpeg 600w, /images/__HASH__-900.jpeg 900w" sizes="100vw">',
' <img',
' alt="My Image Alternative Text" rocket-image="responsive"',
' src="/images/__HASH__-600.jpeg"',
' ',
' ',
' width="600"',
' height="316"',
' loading="lazy"',
' decoding="async"',
' />',
' </picture>',
' <figcaption>My Image Description</figcaption>',
'</figure>',
' </p>',
].join('\n'),
);
}); });
it('can add a pathPrefix that will be used in the build command', async () => { it('can add a pathPrefix that will be used in the build command', async () => {
@@ -119,6 +143,26 @@ describe('RocketCli e2e', () => {
expect(assetHtml).to.equal( expect(assetHtml).to.equal(
'<html><head><link rel="stylesheet" href="../41297ffa.css">\n\n</head><body>\n\n</body></html>', '<html><head><link rel="stylesheet" href="../41297ffa.css">\n\n</head><body>\n\n</body></html>',
); );
let imageHtml = await readBuildOutput(cli, 'image/index.html');
imageHtml = imageHtml.replace(/\.\.\/([a-z0-9]+)\./g, '../__HASH__.');
expect(imageHtml).to.equal(
[
'<html><head>',
'</head><body><p>',
' </p><figure>',
' <picture>',
'<source type="image/avif" srcset="../__HASH__.avif 600w, ../__HASH__.avif 900w" sizes="100vw">',
'<source type="image/jpeg" srcset="../__HASH__.jpeg 600w, ../__HASH__.jpeg 900w" sizes="100vw">',
' <img alt="My Image Alternative Text" rocket-image="responsive" src="../__HASH__.jpeg" width="600" height="316" loading="lazy" decoding="async">',
' </picture>',
' <figcaption>My Image Description</figcaption>',
'</figure>',
' <p></p>',
'',
'',
'</body></html>',
].join('\n'),
);
}); });
it('smoke test for link checking', async () => { it('smoke test for link checking', async () => {

View File

@@ -22,7 +22,10 @@ describe('RocketCli images', () => {
describe('Images', () => { describe('Images', () => {
it('does render content images responsive', async () => { it('does render content images responsive', async () => {
cli = await executeStart('e2e-fixtures/images/rocket.config.js'); cli = await executeStart('e2e-fixtures/images/rocket.config.js');
const indexHtml = await readStartOutput(cli, 'index.html', { formatHtml: true }); const indexHtml = await readStartOutput(cli, 'index.html', {
formatHtml: true,
replaceImageHashes: true,
});
expect(indexHtml).to.equal( expect(indexHtml).to.equal(
[ [
'<p>', '<p>',
@@ -30,18 +33,18 @@ describe('RocketCli images', () => {
' <picture>', ' <picture>',
' <source', ' <source',
' type="image/avif"', ' type="image/avif"',
' srcset="/images/d67643ad-600.avif 600w, /images/d67643ad-900.avif 900w"', ' srcset="/images/__HASH__-600.avif 600w, /images/__HASH__-900.avif 900w"',
' sizes="100vw"', ' sizes="100vw"',
' />', ' />',
' <source', ' <source',
' type="image/jpeg"', ' type="image/jpeg"',
' srcset="/images/d67643ad-600.jpeg 600w, /images/d67643ad-900.jpeg 900w"', ' srcset="/images/__HASH__-600.jpeg 600w, /images/__HASH__-900.jpeg 900w"',
' sizes="100vw"', ' sizes="100vw"',
' />', ' />',
' <img', ' <img',
' alt="My Image Alternative Text"', ' alt="My Image Alternative Text"',
' rocket-image="responsive"', ' rocket-image="responsive"',
' src="/images/d67643ad-600.jpeg"', ' src="/images/__HASH__-600.jpeg"',
' width="600"', ' width="600"',
' height="316"', ' height="316"',
' loading="lazy"', ' loading="lazy"',
@@ -57,47 +60,57 @@ describe('RocketCli images', () => {
it('renders multiple images in the correct order', async () => { it('renders multiple images in the correct order', async () => {
cli = await executeStart('e2e-fixtures/images/rocket.config.js'); cli = await executeStart('e2e-fixtures/images/rocket.config.js');
const indexHtml = await readStartOutput(cli, 'two-images/index.html', { formatHtml: true }); const indexHtml = await readStartOutput(cli, 'two-images/index.html', {
formatHtml: true,
replaceImageHashes: true,
});
expect(indexHtml).to.equal( expect(indexHtml).to.equal(
[ [
'<h2 id="one">',
' <a aria-hidden="true" tabindex="-1" href="#one"><span class="icon icon-link"></span></a>one',
'</h2>',
'<p>', '<p>',
' <picture>', ' <picture>',
' <source', ' <source',
' type="image/avif"', ' type="image/avif"',
' srcset="/images/d67643ad-600.avif 600w, /images/d67643ad-900.avif 900w"', ' srcset="/images/__HASH__-600.avif 600w, /images/__HASH__-900.avif 900w"',
' sizes="100vw"', ' sizes="100vw"',
' />', ' />',
' <source', ' <source',
' type="image/jpeg"', ' type="image/jpeg"',
' srcset="/images/d67643ad-600.jpeg 600w, /images/d67643ad-900.jpeg 900w"', ' srcset="/images/__HASH__-600.jpeg 600w, /images/__HASH__-900.jpeg 900w"',
' sizes="100vw"', ' sizes="100vw"',
' />', ' />',
' <img', ' <img',
' alt="one"', ' alt="one"',
' rocket-image="responsive"', ' rocket-image="responsive"',
' src="/images/d67643ad-600.jpeg"', ' src="/images/__HASH__-600.jpeg"',
' width="600"', ' width="600"',
' height="316"', ' height="316"',
' loading="lazy"', ' loading="lazy"',
' decoding="async"', ' decoding="async"',
' />', ' />',
' </picture>', ' </picture>',
'', '</p>',
'<h2 id="two">',
' <a aria-hidden="true" tabindex="-1" href="#two"><span class="icon icon-link"></span></a>two',
'</h2>',
'<p>',
' <picture>', ' <picture>',
' <source', ' <source',
' type="image/avif"', ' type="image/avif"',
' srcset="/images/d67643ad-600.avif 600w, /images/d67643ad-900.avif 900w"', ' srcset="/images/__HASH__-600.avif 600w, /images/__HASH__-900.avif 900w"',
' sizes="100vw"', ' sizes="100vw"',
' />', ' />',
' <source', ' <source',
' type="image/jpeg"', ' type="image/jpeg"',
' srcset="/images/d67643ad-600.jpeg 600w, /images/d67643ad-900.jpeg 900w"', ' srcset="/images/__HASH__-600.jpeg 600w, /images/__HASH__-900.jpeg 900w"',
' sizes="100vw"', ' sizes="100vw"',
' />', ' />',
' <img', ' <img',
' alt="two"', ' alt="two"',
' rocket-image="responsive"', ' rocket-image="responsive"',
' src="/images/d67643ad-600.jpeg"', ' src="/images/__HASH__-600.jpeg"',
' width="600"', ' width="600"',
' height="316"', ' height="316"',
' loading="lazy"', ' loading="lazy"',
@@ -111,7 +124,10 @@ describe('RocketCli images', () => {
it('can configure those responsive images', async () => { it('can configure those responsive images', async () => {
cli = await executeStart('e2e-fixtures/images/small.rocket.config.js'); cli = await executeStart('e2e-fixtures/images/small.rocket.config.js');
const indexHtml = await readStartOutput(cli, 'index.html', { formatHtml: true }); const indexHtml = await readStartOutput(cli, 'index.html', {
formatHtml: true,
replaceImageHashes: true,
});
expect(indexHtml).to.equal( expect(indexHtml).to.equal(
[ [
'<p>', '<p>',
@@ -119,18 +135,18 @@ describe('RocketCli images', () => {
' <picture>', ' <picture>',
' <source', ' <source',
' type="image/avif"', ' type="image/avif"',
' srcset="/images/d67643ad-30.avif 30w, /images/d67643ad-60.avif 60w"', ' srcset="/images/__HASH__-30.avif 30w, /images/__HASH__-60.avif 60w"',
' sizes="(min-width: 1024px) 30px, 60px"', ' sizes="(min-width: 1024px) 30px, 60px"',
' />', ' />',
' <source', ' <source',
' type="image/jpeg"', ' type="image/jpeg"',
' srcset="/images/d67643ad-30.jpeg 30w, /images/d67643ad-60.jpeg 60w"', ' srcset="/images/__HASH__-30.jpeg 30w, /images/__HASH__-60.jpeg 60w"',
' sizes="(min-width: 1024px) 30px, 60px"', ' sizes="(min-width: 1024px) 30px, 60px"',
' />', ' />',
' <img', ' <img',
' alt="My Image Alternative Text"', ' alt="My Image Alternative Text"',
' rocket-image="responsive"', ' rocket-image="responsive"',
' src="/images/d67643ad-30.jpeg"', ' src="/images/__HASH__-30.jpeg"',
' width="30"', ' width="30"',
' height="15"', ' height="15"',
' loading="lazy"', ' loading="lazy"',
@@ -146,25 +162,28 @@ describe('RocketCli images', () => {
it('will only render a figure & figcaption if there is a caption/title', async () => { it('will only render a figure & figcaption if there is a caption/title', async () => {
cli = await executeStart('e2e-fixtures/images/small.rocket.config.js'); cli = await executeStart('e2e-fixtures/images/small.rocket.config.js');
const indexHtml = await readStartOutput(cli, 'no-title/index.html', { formatHtml: true }); const indexHtml = await readStartOutput(cli, 'no-title/index.html', {
formatHtml: true,
replaceImageHashes: true,
});
expect(indexHtml).to.equal( expect(indexHtml).to.equal(
[ [
'<p>', '<p>',
' <picture>', ' <picture>',
' <source', ' <source',
' type="image/avif"', ' type="image/avif"',
' srcset="/images/d67643ad-30.avif 30w, /images/d67643ad-60.avif 60w"', ' srcset="/images/__HASH__-30.avif 30w, /images/__HASH__-60.avif 60w"',
' sizes="(min-width: 1024px) 30px, 60px"', ' sizes="(min-width: 1024px) 30px, 60px"',
' />', ' />',
' <source', ' <source',
' type="image/jpeg"', ' type="image/jpeg"',
' srcset="/images/d67643ad-30.jpeg 30w, /images/d67643ad-60.jpeg 60w"', ' srcset="/images/__HASH__-30.jpeg 30w, /images/__HASH__-60.jpeg 60w"',
' sizes="(min-width: 1024px) 30px, 60px"', ' sizes="(min-width: 1024px) 30px, 60px"',
' />', ' />',
' <img', ' <img',
' alt="My Image Alternative Text"', ' alt="My Image Alternative Text"',
' rocket-image="responsive"', ' rocket-image="responsive"',
' src="/images/d67643ad-30.jpeg"', ' src="/images/__HASH__-30.jpeg"',
' width="30"', ' width="30"',
' height="15"', ' height="15"',
' loading="lazy"', ' loading="lazy"',
@@ -178,15 +197,18 @@ describe('RocketCli images', () => {
it('will render an img with srcset and sizes if there is only one image format', async () => { it('will render an img with srcset and sizes if there is only one image format', async () => {
cli = await executeStart('e2e-fixtures/images/single-format.rocket.config.js'); cli = await executeStart('e2e-fixtures/images/single-format.rocket.config.js');
const indexHtml = await readStartOutput(cli, 'no-title/index.html', { formatHtml: true }); const indexHtml = await readStartOutput(cli, 'no-title/index.html', {
formatHtml: true,
replaceImageHashes: true,
});
expect(indexHtml).to.equal( expect(indexHtml).to.equal(
[ [
'<p>', '<p>',
' <img', ' <img',
' alt="My Image Alternative Text"', ' alt="My Image Alternative Text"',
' rocket-image="responsive"', ' rocket-image="responsive"',
' src="/images/d67643ad-30.jpeg"', ' src="/images/__HASH__-30.jpeg"',
' srcset="/images/d67643ad-30.jpeg 30w, /images/d67643ad-60.jpeg 60w"', ' srcset="/images/__HASH__-30.jpeg 30w, /images/__HASH__-60.jpeg 60w"',
' sizes="(min-width: 1024px) 30px, 60px"', ' sizes="(min-width: 1024px) 30px, 60px"',
' width="30"', ' width="30"',
' height="15"', ' height="15"',

View File

@@ -108,15 +108,18 @@ describe('RocketCli preset', () => {
it('a preset can provide an adjustImagePresets() function', async () => { it('a preset can provide an adjustImagePresets() function', async () => {
cli = await executeStart('preset-fixtures/use-preset/rocket.config.js'); cli = await executeStart('preset-fixtures/use-preset/rocket.config.js');
const indexHtml = await readStartOutput(cli, 'index.html', { formatHtml: true }); const indexHtml = await readStartOutput(cli, 'index.html', {
formatHtml: true,
replaceImageHashes: true,
});
expect(indexHtml).to.equal( expect(indexHtml).to.equal(
[ [
'<p>', '<p>',
' <img', ' <img',
' alt="My Image Alternative Text"', ' alt="My Image Alternative Text"',
' rocket-image="responsive"', ' rocket-image="responsive"',
' src="/images/1f847765-30.jpeg"', ' src="/images/__HASH__-30.jpeg"',
' srcset="/images/1f847765-30.jpeg 30w, /images/1f847765-60.jpeg 60w"', ' srcset="/images/__HASH__-30.jpeg 30w, /images/__HASH__-60.jpeg 60w"',
' sizes="30px"', ' sizes="30px"',
' width="30"', ' width="30"',
' height="15"', ' height="15"',

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -0,0 +1,5 @@
---
layout: layout-raw
---
![My Image Alternative Text](./_assets/my-image.jpg 'My Image Description')

View File

@@ -2,4 +2,10 @@
layout: layout-raw layout: layout-raw
--- ---
![one](./_assets/my-image.jpg)![two](./_assets/my-image.jpg) ## one
![one](./_assets/my-image.jpg)
## two
![two](./_assets/my-image.jpg)

View File

@@ -25,6 +25,7 @@ const config = {
}), }),
], ],
// serviceWorkerName: 'sw.js', // serviceWorkerName: 'sw.js',
// pathPrefix: '/_site/',
// emptyOutputDir: false, // emptyOutputDir: false,
}; };