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

Adds a --css-modules option #370

Merged
merged 7 commits into from
Feb 9, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,26 @@ Acts just like `microbundle build`, but watches your source files and rebuilds o

Just point the input to a `.ts` file through either the cli or the `source` key in your `package.json` and you’re done.

### Using CSS Modules

By default any css file imported as `.module.css`, will be treated as a css-module. If you wish to treat all .css
imports as a module, specify the cli flag `--css-modules true`. If you wish to disable all css-module behaviours set the
flag to `false`.

The default scope name when css-modules is turned on will be, in watch mode `_[name]__[local]__[hash:base64:5]` and when
you build `_[hash:base64:5]`. This can be overriden by specifying the flag, eg
`--css-modules "_something_[hash:base64:7]"`. _Note:_ by setting this, it will be treated as a true, and thus, all .css
imports will be scoped.

| flag | import | is css module? |
| ----- | ------------------------------ | :----------------: |
| null | import './my-file.css'; | :x: |
| null | import './my-file.module.css'; | :white_check_mark: |
| false | import './my-file.css'; | :x: |
| false | import './my-file.module.css'; | :x: |
| true | import './my-file.css'; | :white_check_mark: |
| true | import './my-file.module.css'; | :white_check_mark: |

### Specifying builds in `package.json`

You can specify output builds in a `package.json` as follows:
Expand Down Expand Up @@ -151,6 +171,7 @@ Options
--raw Show raw byte size (default false)
--jsx A custom JSX pragma like React.createElement (default: h)
--tsconfig Specify the path to a custom tsconfig.json
--css-modules Configures .css to be treated as modules (default: null)
-h, --help Displays this message

Examples
Expand Down
52 changes: 52 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,8 @@ function createConfig(options, entry, format, writeMeta) {
preset: 'default',
}),
].filter(Boolean),
autoModules: shouldCssModules(options),
modules: cssModulesConfig(options),
// only write out CSS for the first bundle (avoids pointless extra files):
inject: false,
extract: !!writeMeta,
Expand Down Expand Up @@ -664,3 +666,53 @@ function createConfig(options, entry, format, writeMeta) {

return config;
}

function shouldCssModules(options) {
const passedInOption = processCssmodulesArgument(options);

// We should module when my-file.module.css or my-file.css
const moduleAllCss = passedInOption === true;

// We should module when my-file.module.css
const allowOnlySuffixModule = passedInOption === null;

return moduleAllCss || allowOnlySuffixModule;
}

function cssModulesConfig(options) {
const passedInOption = processCssmodulesArgument(options);
const isWatchMode = options.watch;
const hasPassedInScopeName = !(
typeof passedInOption === 'boolean' || passedInOption === null
);

if (shouldCssModules(options) || hasPassedInScopeName) {
let generateScopedName = isWatchMode
? '_[name]__[local]__[hash:base64:5]'
: '_[hash:base64:5]';

if (hasPassedInScopeName) {
generateScopedName = passedInOption; // would be the string from --css-modules "_[hash]".
}

return { generateScopedName };
}

return false;
}

/*
This is done becuase if you use the cli default property, you get a primiatve "null" or "false",
but when using the cli arguments, you always get back strings. This method aims at correcting those
for both realms. So that both realms _convert_ into primatives.
*/
function processCssmodulesArgument(options) {
if (options['css-modules'] === 'true' || options['css-modules'] === true)
return true;
if (options['css-modules'] === 'false' || options['css-modules'] === false)
return false;
if (options['css-modules'] === 'null' || options['css-modules'] === null)
return null;

return options['css-modules'];
}
5 changes: 5 additions & 0 deletions src/prog.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ export default handler => {
.option('--name', 'Specify name exposed in UMD builds')
.option('--cwd', 'Use an alternative working directory', '.')
.option('--sourcemap', 'Generate source map', true)
.option(
'--css-modules',
'Turns on css-modules for all .css imports. Passing a string will override the scopeName. eg --css-modules="_[hash]"',
null,
maraisr marked this conversation as resolved.
Show resolved Hide resolved
)
.example("microbundle --no-sourcemap # don't generate sourcemaps")
.option('--raw', 'Show raw byte size', false)
.option(
Expand Down
198 changes: 197 additions & 1 deletion test/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ Build \\"basicCss\\" to dist:

exports[`fixtures build basic-css with microbundle 2`] = `7`;

exports[`fixtures build basic-css with microbundle 3`] = `".testing{display:-webkit-box;display:flex;color:red;background:#00f}"`;
exports[`fixtures build basic-css with microbundle 3`] = `"._rHGVB{display:-webkit-box;display:flex;color:red;background:#00f}"`;

exports[`fixtures build basic-css with microbundle 4`] = `
"export default function(){var e=document.createElement(\\"div\\");return e.className=\\"testing\\",e}
Expand Down Expand Up @@ -1043,6 +1043,202 @@ exports[`fixtures build class-properties with microbundle 5`] = `
"
`;

exports[`fixtures build css-modules--false with microbundle 1`] = `
"Used script: microbundle --no-sourcemap --css-modules false

Directory tree:

css-modules--false
dist
css-modules--false.css
css-modules--false.esm.js
css-modules--false.js
css-modules--false.umd.js
package.json
src
index.js
not_scoped.css
not_scoped.module.css


Build \\"cssModulesFalse\\" to dist:
49 B: css-modules--false.js.gz
23 B: css-modules--false.js.br
48 B: css-modules--false.esm.js.gz
32 B: css-modules--false.esm.js.br
157 B: css-modules--false.umd.js.gz
110 B: css-modules--false.umd.js.br"
`;

exports[`fixtures build css-modules--false with microbundle 2`] = `4`;

exports[`fixtures build css-modules--false with microbundle 3`] = `
"body{display:-webkit-box;display:flex;color:red;background:#00f}.test_class_that_shouldnt_be_scoped{background-color:#00f}
.not_scoped_class{color:pink}"
`;

exports[`fixtures build css-modules--false with microbundle 4`] = `
"export default function(){}
"
`;

exports[`fixtures build css-modules--false with microbundle 5`] = `
"module.exports=function(){};
"
`;

exports[`fixtures build css-modules--false with microbundle 6`] = `
"!function(e,n){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?module.exports=function(){}:\\"function\\"==typeof define&&define.amd?define(function(){return function(){}}):(e=e||self).cssModulesFalse=function(){}}(this);
"
`;

exports[`fixtures build css-modules--null with microbundle 1`] = `
"Used script: microbundle --no-sourcemap

Directory tree:

css-modules--null
dist
css-modules--null.css
css-modules--null.esm.js
css-modules--null.js
css-modules--null.umd.js
package.json
src
index.js
not_scoped.css
scoped.module.css


Build \\"cssModulesNull\\" to dist:
110 B: css-modules--null.js.gz
72 B: css-modules--null.js.br
109 B: css-modules--null.esm.js.gz
70 B: css-modules--null.esm.js.br
201 B: css-modules--null.umd.js.gz
142 B: css-modules--null.umd.js.br"
`;

exports[`fixtures build css-modules--null with microbundle 2`] = `4`;

exports[`fixtures build css-modules--null with microbundle 3`] = `
"body{display:-webkit-box;display:flex;color:red;background:#00f}._2Dgv6{background-color:#00f}
._2kWDE{color:pink}"
`;

exports[`fixtures build css-modules--null with microbundle 4`] = `
"export default function(){var e=document.createElement(\\"div\\");return e.className=\\"_2kWDE\\",e}
"
`;

exports[`fixtures build css-modules--null with microbundle 5`] = `
"module.exports=function(){var e=document.createElement(\\"div\\");return e.className=\\"_2kWDE\\",e};
"
`;

exports[`fixtures build css-modules--null with microbundle 6`] = `
"!function(e,n){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?module.exports=n():\\"function\\"==typeof define&&define.amd?define(n):(e=e||self).cssModulesNull=n()}(this,function(){return function(){var e=document.createElement(\\"div\\");return e.className=\\"_2kWDE\\",e}});
"
`;

exports[`fixtures build css-modules--string with microbundle 1`] = `
"Used script: microbundle --no-sourcemap --css-modules '_contains_this_[hash]'

Directory tree:

css-modules--string
dist
css-modules--string.css
css-modules--string.esm.js
css-modules--string.js
css-modules--string.umd.js
package.json
src
index.js
scoped.css
scoped.module.css


Build \\"cssModulesString\\" to dist:
166 B: css-modules--string.js.gz
118 B: css-modules--string.js.br
166 B: css-modules--string.esm.js.gz
117 B: css-modules--string.esm.js.br
264 B: css-modules--string.umd.js.gz
193 B: css-modules--string.umd.js.br"
`;

exports[`fixtures build css-modules--string with microbundle 2`] = `4`;

exports[`fixtures build css-modules--string with microbundle 3`] = `
"body{display:-webkit-box;display:flex;color:red;background:#00f}._contains_this_81567d0efc15a456670452d3277e1a68{background-color:#00f}
._contains_this_0a8c24df242c2cd708036873307aea94{color:pink}"
`;

exports[`fixtures build css-modules--string with microbundle 4`] = `
"export default function(){var a=document.createElement(\\"div\\");return a.className=\\"_contains_this_0a8c24df242c2cd708036873307aea94 _contains_this_81567d0efc15a456670452d3277e1a68\\",a}
"
`;

exports[`fixtures build css-modules--string with microbundle 5`] = `
"module.exports=function(){var e=document.createElement(\\"div\\");return e.className=\\"_contains_this_0a8c24df242c2cd708036873307aea94 _contains_this_81567d0efc15a456670452d3277e1a68\\",e};
"
`;

exports[`fixtures build css-modules--string with microbundle 6`] = `
"!function(e,n){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?module.exports=n():\\"function\\"==typeof define&&define.amd?define(n):(e=e||self).cssModulesString=n()}(this,function(){return function(){var e=document.createElement(\\"div\\");return e.className=\\"_contains_this_0a8c24df242c2cd708036873307aea94 _contains_this_81567d0efc15a456670452d3277e1a68\\",e}});
"
`;

exports[`fixtures build css-modules--true with microbundle 1`] = `
"Used script: microbundle --no-sourcemap --css-modules true

Directory tree:

css-modules--true
dist
css-modules--true.css
css-modules--true.esm.js
css-modules--true.js
css-modules--true.umd.js
package.json
src
index.js
scoped.css
scoped.module.css


Build \\"cssModulesTrue\\" to dist:
118 B: css-modules--true.js.gz
80 B: css-modules--true.js.br
117 B: css-modules--true.esm.js.gz
77 B: css-modules--true.esm.js.br
212 B: css-modules--true.umd.js.gz
149 B: css-modules--true.umd.js.br"
`;

exports[`fixtures build css-modules--true with microbundle 2`] = `4`;

exports[`fixtures build css-modules--true with microbundle 3`] = `
"body{display:-webkit-box;display:flex;color:red;background:#00f}._1E6DU{background-color:#00f}
._2kWDE{color:pink}"
`;

exports[`fixtures build css-modules--true with microbundle 4`] = `
"export default function(){var e=document.createElement(\\"div\\");return e.className=\\"_2kWDE _1E6DU\\",e}
"
`;

exports[`fixtures build css-modules--true with microbundle 5`] = `
"module.exports=function(){var e=document.createElement(\\"div\\");return e.className=\\"_2kWDE _1E6DU\\",e};
"
`;

exports[`fixtures build css-modules--true with microbundle 6`] = `
"!function(e,n){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?module.exports=n():\\"function\\"==typeof define&&define.amd?define(n):(e=e||self).cssModulesTrue=n()}(this,function(){return function(){var e=document.createElement(\\"div\\");return e.className=\\"_2kWDE _1E6DU\\",e}});
"
`;

exports[`fixtures build custom-babelrc with microbundle 1`] = `
"Used script: microbundle

Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/css-modules--false/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "css-modules--false",
"scripts": {
"build": "microbundle --no-sourcemap --css-modules false"
}
}
4 changes: 4 additions & 0 deletions test/fixtures/css-modules--false/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import './not_scoped.css';
import './not_scoped.module.css';

export default function() {}
9 changes: 9 additions & 0 deletions test/fixtures/css-modules--false/src/not_scoped.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
body {
display: flex;
color: red;
background: blue;
}

.test_class_that_shouldnt_be_scoped {
background-color: blue;
}
3 changes: 3 additions & 0 deletions test/fixtures/css-modules--false/src/not_scoped.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.not_scoped_class {
color: pink;
}
6 changes: 6 additions & 0 deletions test/fixtures/css-modules--null/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "css-modules--null",
"scripts": {
"build": "microbundle --no-sourcemap"
}
}
8 changes: 8 additions & 0 deletions test/fixtures/css-modules--null/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import './not_scoped.css';
import scoped from './scoped.module.css';

export default function() {
const el = document.createElement('div');
el.className = scoped.scoped_class;
return el;
}
9 changes: 9 additions & 0 deletions test/fixtures/css-modules--null/src/not_scoped.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
body {
display: flex;
color: red;
background: blue;
}

.test_class_that_shouldnt_be_scoped {
background-color: blue;
}
3 changes: 3 additions & 0 deletions test/fixtures/css-modules--null/src/scoped.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.scoped_class {
color: pink;
}
6 changes: 6 additions & 0 deletions test/fixtures/css-modules--string/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "css-modules--string",
"scripts": {
"build": "microbundle --no-sourcemap --css-modules '_contains_this_[hash]'"
}
}
9 changes: 9 additions & 0 deletions test/fixtures/css-modules--string/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import global from './scoped.css';
import scoped from './scoped.module.css';

export default function() {
const el = document.createElement('div');
el.className =
scoped.scoped_class + ' ' + global.test_class_that_should_be_scoped;
return el;
}
Loading