Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process CSS in SVGs #6743

Merged
merged 19 commits into from
Aug 28, 2021
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions flow-libs/posthtml.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ declare module 'posthtml' {

declare type PostHTMLTree = Array<PostHTMLNode>;
declare type PostHTMLOptions = {
sync: Boolean,
skipParse: Boolean,
sync?: Boolean,
skipParse?: Boolean,
...
};
declare type PostHTMLMessage = {
Expand All @@ -41,11 +41,16 @@ declare module 'posthtml' {
messages: Array<PostHTMLMessage>,
...
}>;
declare var match: (
expression: string | RegExp | Object | Array,
cb: (node: PostHTMLNode) => PostHTMLNode | PostHTMLNode[],
) => void;

declare class Api {
static walk: typeof walk;
walk: typeof walk;
process: typeof process;
match: typeof match;
}

declare class PostHTML extends Api {
Expand Down
2 changes: 2 additions & 0 deletions packages/configs/default/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"style:*.vue": ["@parcel/transformer-vue"],
"custom:*.vue": ["@parcel/transformer-vue"],
"*.{png,jpg,jpeg,webp}": ["@parcel/transformer-image"],
"*.svg": ["@parcel/transformer-svg"],
"url:*": ["...", "@parcel/transformer-raw"]
},
"namers": ["@parcel/namer-default"],
Expand All @@ -59,6 +60,7 @@
"*.html": "@parcel/packager-html",
"*.css": "@parcel/packager-css",
"*.{js,mjs,cjs}": "@parcel/packager-js",
"*.svg": "@parcel/packager-svg",
"*.ts": "@parcel/packager-ts",
"*.{jsonld,webmanifest}": "@parcel/packager-raw-url",
"*": "@parcel/packager-raw"
Expand Down
4 changes: 3 additions & 1 deletion packages/configs/default/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@parcel/packager-html": "2.0.0-rc.0",
"@parcel/packager-js": "2.0.0-rc.0",
"@parcel/packager-raw": "2.0.0-rc.0",
"@parcel/packager-svg": "2.0.0-rc.0",
"@parcel/reporter-dev-server": "2.0.0-rc.0",
"@parcel/resolver-default": "2.0.0-rc.0",
"@parcel/runtime-browser-hmr": "2.0.0-rc.0",
Expand All @@ -41,7 +42,8 @@
"@parcel/transformer-postcss": "2.0.0-rc.0",
"@parcel/transformer-posthtml": "2.0.0-rc.0",
"@parcel/transformer-raw": "2.0.0-rc.0",
"@parcel/transformer-react-refresh-wrap": "2.0.0-rc.0"
"@parcel/transformer-react-refresh-wrap": "2.0.0-rc.0",
"@parcel/transformer-svg": "2.0.0-rc.0"
},
"parcelDependencies": {
"@parcel/optimizer-data-url": "2.0.0-rc.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "@parcel/config-default",
"transformers": {
"*.svg": ["@parcel/transformer-svg-react"]
"*.svg": ["...", "@parcel/transformer-svg-react"]
},
"reporters": []
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:root {
fill: red
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:root {
fill: red;
font-family: serif;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:root {
font-family: sans-serif;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:root {
font-family: monospace;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:root {
font-family: cursive;
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<title>Other page 1</title>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<title>Other page 2</title>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions packages/core/integration-tests/test/svg-react.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import assert from 'assert';
import {bundle, outputFS} from '@parcel/test-utils';
import path from 'path';

describe('svg-react', function() {
it('should support transforming SVGs to react components', async function() {
let b = await bundle(
path.join(__dirname, '/integration/svg-react/react.js'),
{
defaultConfig: path.join(
__dirname,
'integration/custom-configs/.parcelrc-svg-react',
),
},
);

let file = await outputFS.readFile(b.getBundles()[0].filePath, 'utf-8');
assert(!file.includes('inkscape'));
assert(file.includes('function SvgIcon'));
assert(file.includes('_react.createElement("svg"'));
});
});
90 changes: 76 additions & 14 deletions packages/core/integration-tests/test/svg.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
import assert from 'assert';
import {bundle, outputFS} from '@parcel/test-utils';
import {assertBundles, bundle, distDir, outputFS} from '@parcel/test-utils';
import path from 'path';

describe('svg', function() {
it('should support bundling SVG', async () => {
let b = await bundle(path.join(__dirname, '/integration/svg/circle.svg'));

assertBundles(b, [
{
name: 'circle.svg',
assets: ['circle.svg'],
},
{
name: 'other1.html',
assets: ['other1.html'],
},
{
type: 'svg',
assets: ['square.svg'],
},
{
name: 'other2.html',
assets: ['other2.html'],
},
]);
});

it('should minify SVG bundles', async function() {
let b = await bundle(path.join(__dirname, '/integration/svg/index.html'), {
let b = await bundle(path.join(__dirname, '/integration/svg/circle.svg'), {
defaultTargetOptions: {
shouldOptimize: true,
},
Expand All @@ -14,7 +37,7 @@ describe('svg', function() {
b.getBundles().find(b => b.type === 'svg').filePath,
'utf-8',
);
assert(!file.includes('inkscape'));
assert(!file.includes('comment'));
});

it('support SVGO config files', async function() {
Expand All @@ -35,17 +58,56 @@ describe('svg', function() {
assert(file.includes('comment'));
});

it('should support transforming SVGs to react components', async function() {
let b = await bundle(path.join(__dirname, '/integration/svg/react.js'), {
defaultConfig: path.join(
__dirname,
'integration/custom-configs/.parcelrc-svg',
),
});
it('should turn xml-stylesheet processing instructions into styles', async function() {
const b = await bundle(
path.join(__dirname, '/integration/svg-xml-stylesheet/img.svg'),
);

let file = await outputFS.readFile(b.getBundles()[0].filePath, 'utf-8');
assert(!file.includes('inkscape'));
assert(file.includes('function SvgIcon'));
assert(file.includes('_react.createElement("svg"'));
assertBundles(b, [
{
name: 'img.svg',
assets: ['img.svg'],
},
{
type: 'css',
assets: ['img.svg', 'style1.css', 'style3.css'],
},
]);

const svg = await outputFS.readFile(
b.getBundles().find(b => b.type === 'svg').filePath,
'utf-8',
);

assert(!svg.includes('style1.css'));
assert(!svg.includes('style3.css'));
assert(svg.includes('style2.css'));
assert(svg.includes('<?xml-not-a-stylesheet'));
assert(svg.includes('<style>'));
assert(!svg.includes('@import'));
assert(svg.includes(':root {\n fill: red;\n font-family: serif;\n}'));
assert(svg.includes(':root {\n font-family: monospace;\n}\n'));
thewilkybarkid marked this conversation as resolved.
Show resolved Hide resolved
});

it('should handle CSS with @imports', async function() {
const b = await bundle(
path.join(__dirname, '/integration/svg-css-import/img.svg'),
);

assertBundles(b, [
{
type: 'css',
assets: ['img.svg', 'test.css'],
},
{
name: 'img.svg',
assets: ['img.svg'],
},
]);

const svg = await outputFS.readFile(path.join(distDir, 'img.svg'), 'utf8');

assert(!svg.includes('@import'));
assert(svg.includes(':root {\n fill: red\n}'));
});
});
28 changes: 28 additions & 0 deletions packages/packagers/svg/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "@parcel/packager-svg",
"version": "2.0.0-rc.0",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"repository": {
"type": "git",
"url": "https://github.com/parcel-bundler/parcel.git"
},
"main": "lib/SVGPackager.js",
"source": "src/SVGPackager.js",
"engines": {
"node": ">= 12.0.0",
"parcel": "^2.0.0-rc.0"
},
"dependencies": {
"@parcel/plugin": "2.0.0-rc.0",
"@parcel/types": "2.0.0-rc.0",
"@parcel/utils": "2.0.0-rc.0",
"posthtml": "^0.16.4"
}
}
Loading