https://github.com/chinanf-boy/microbundle-explain
explain : microbundle 0 config bundler for tiny modules. 0配置构建小模块 power by rollup
https://github.com/chinanf-boy/microbundle-explain
bundle explain microbundle rollup
Last synced: 11 months ago
JSON representation
explain : microbundle 0 config bundler for tiny modules. 0配置构建小模块 power by rollup
- Host: GitHub
- URL: https://github.com/chinanf-boy/microbundle-explain
- Owner: chinanf-boy
- Created: 2018-02-09T09:28:44.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-02-09T09:28:55.000Z (about 8 years ago)
- Last Synced: 2025-02-08T08:47:13.737Z (about 1 year ago)
- Topics: bundle, explain, microbundle, rollup
- Language: JavaScript
- Size: 6.84 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# microbundle
由`Rollup`提供支持的小型模块的零配置打包程序。by [developit](https://github.com/developit)
[](https://github.com/chinanf-boy/Source-Explain)
Explanation
> "version": "1.0.0"
[github source](https://github.com/developit/microbundle)
~~[english](./README.en.md)~~
---
懒惰才能使人进步😊
---
## 目录
---
## 使用
``` js
microbundle
//
microbundle build
```
默认情况下, 会在项目根目录-package.json- `main` 字样, 当然你也可以指定
> 你可以看看作者对 此项目-microbundle 的[使用项目-greenlet](https://github.com/developit/greenlet/blob/master/package.json#L10)
> 更可以看看-[greenlet-explain](https://github.com/chinanf-boy/greenlet-explain)
---
## package
``` js
"main": "dist/microbundle.js", // 构建的
"source": "src/index.js", // 源码
"bin": "dist/cli.js", // 终端命令
```
## cli
既然💪-microbundle-💪 是通过
`microbundle` 启动构建的
我们自然从命令代码开始
``` js
#!/usr/bin/env node
import sade from 'sade'; // 命令解析
import microbundle from '.';
let { version } = require('../package');
let prog = sade('microbundle');
let toArray = val => Array.isArray(val) ? val : val == null ? [] : [val];
// 变 数组
prog
.version(version)
.option('--entry, -i', 'Entry module(s)')
.option('--output, -o', 'Directory to place build files into')
.option('--format, -f', 'Only build specified formats', 'es,cjs,umd')
.option('--target', 'Specify your target environment', 'node')
.option('--external', `Specify external dependencies, or 'all'`)
.option('--compress', 'Compress output using UglifyJS', true)
.option('--strict', 'Enforce undefined global context and add "use strict"')
.option('--name', 'Specify name exposed in UMD builds')
.option('--cwd', 'Use an alternative working directory', '.');
// 第一个变量 命令选项 第二个变量 说明 第三个变量 默认值
prog
.command('build [...entries]', '', { default: true })
.describe('Build once and exit')
.action(run);
prog
.command('watch [...entries]')
.describe('Rebuilds on any change')
.action((str, opts) => run(str, opts, true));
// Parse argv; add extra aliases
prog.parse(process.argv, {
alias: {
o: ['output', 'd'],
i: ['entry', 'entries', 'e']
}
});
// 这个命令解析库-api-其实都挺好懂的
// 主要是 run
function run(str, opts, isWatch) {
opts.watch = !!isWatch;
opts.entries = toArray(str || opts.entry).concat(opts._);
microbundle(opts) // 用 sade 解析来的命令给予 microbundle
.then( output => {
if (output!=null) process.stdout.write(output + '\n');
// 把有色的结果-输出终端
if (!opts.watch) process.exit(0);
})
.catch(err => {
process.stderr.write(String(err) + '\n');
// 把有色的结果-输出终端
process.exit(err.code || 1);
});
}
```
## index
我们先直入主题 [`microbundle`](#microbundle-async) | [从头开始-代码1](#导入)
### 导入
代码 1- 22
``` js
import 'acorn-jsx';
import fs from 'fs';
import { resolve, relative, dirname, basename, extname } from 'path';
import chalk from 'chalk'; // 终端-有色-输出
import { map, series } from 'asyncro';
import promisify from 'es6-promisify';
import glob from 'glob';
import autoprefixer from 'autoprefixer';
import { rollup, watch } from 'rollup';
import nodent from 'rollup-plugin-nodent';
import commonjs from 'rollup-plugin-commonjs';
import nodeResolve from 'rollup-plugin-node-resolve';
import buble from 'rollup-plugin-buble';
import uglify from 'rollup-plugin-uglify';
import postcss from 'rollup-plugin-postcss';
import alias from 'rollup-plugin-strict-alias';
import gzipSize from 'gzip-size';
import prettyBytes from 'pretty-bytes';
import shebangPlugin from 'rollup-plugin-preserve-shebang';
import typescript from 'rollup-plugin-typescript';
import flow from './lib/flow-plugin';
import camelCase from 'camelcase';
```
### index-变量
``` js
const readFile = promisify(fs.readFile);
const stat = promisify(fs.stat);
const isDir = name => stat(name).then( stats => stats.isDirectory() ).catch( () => false );
const isFile = name => stat(name).then( stats => stats.isFile() ).catch( () => false );
const removeScope = name => name.replace(/^@.*\//, '');
const safeVariableName = name => camelCase(removeScope(name).toLowerCase().replace(/((^[^a-zA-Z]+)|[^\w.-])|([^a-zA-Z0-9]+$)/g, ''));
const WATCH_OPTS = {
exclude: 'node_modules/**'
};
```
### microbundle-async
定义-异步-主函数
代码 35-135
``` js
export default async function microbundle(options) {
let cwd = options.cwd = resolve(process.cwd(), options.cwd), // 命令路径
hasPackageJson = true;
try {
options.pkg = JSON.parse(await readFile(resolve(cwd, 'package.json'), 'utf8')); // 路径中的 - package.json - 文件
}
catch (err) {
process.stderr.write(chalk.yellow(`${chalk.yellow.inverse('WARN')} no package.json found. Assuming a name of "${basename(options.cwd)}".`)+'\n');
let msg = String(err.message || err);
if (!msg.match(/ENOENT/)) console.warn(` ${chalk.red.dim(msg)}`);
options.pkg = {};
hasPackageJson = false;
}
if (!options.pkg.name) {
options.pkg.name = basename(options.cwd); // 项目名
if (hasPackageJson) {
process.stderr.write(chalk.yellow(`${chalk.yellow.inverse('WARN')} missing package.json "name" field. Assuming "${options.pkg.name}".`)+'\n');
}
}
const jsOrTs = async filename => resolve(cwd, `${filename}${await isFile(resolve(cwd, filename+'.ts')) ? '.ts' : '.js'}`);
// 是 js 还是 ts 文件
options.input = [];
[].concat(
options.entries && options.entries.length ? options.entries : options.pkg.source || (await isDir(resolve(cwd, 'src')) && await jsOrTs('src/index')) || await jsOrTs('index') || options.pkg.module
).map( file => glob.sync(resolve(cwd, file)) ).forEach( file => options.input.push(...file) );
// 从 定义的目录 or 文件 或 默认中找出-入口文件
let main = resolve(cwd, options.output || options.pkg.main || 'dist');
// 输出位置|文件-初始化
if (!main.match(/\.[a-z]+$/) || await isDir(main)) {
// 当 main不符合文件名规范 或者 是目录
main = resolve(main, `${removeScope(options.pkg.name)}.js`);
// 重定义-输出文件
}
options.output = main;
let entries = (await map([].concat(options.input), async file => {
file = resolve(cwd, file);
if (await isDir(file)) {
file = resolve(file, 'index.js');
}
return file; // 加入目录
})).filter( (item, i, arr) => arr.indexOf(item)===i ); // 去掉多余
options.entries = entries;
options.multipleEntries = entries.length>1;
let formats = (options.format || options.formats).split(','); // 是否有-构建输出文件类型-要求
// always compile cjs first if it's there:
// 总是构建 cjs 类型 优先
formats.sort( (a, b) => a==='cjs' ? -1 : a>b ? 1 : 0);
let steps = [];
for (let i=0; i一步一步添加
}
}
```
- [createConfig 配置好 rollup构建所需配置](./createConfig.readme.md)
---
``` js
async function getSizeInfo(code, filename) {
let size = await gzipSize(code);
let prettySize = prettyBytes(size);
let color = size < 5000 ? 'green' : size > 40000 ? 'red' : 'yellow';
return `${' '.repeat(10-prettySize.length)}${chalk[color](prettySize)}: ${chalk.white(basename(filename))}`;
// 显示-文件大小
}
if (options.watch) { // 监听
const onBuild = options.onBuild;
return new Promise( (resolve, reject) => {
process.stdout.write(chalk.blue(`Watching source, compiling to ${relative(cwd, dirname(options.output))}:\n`));
steps.map( options => {
watch(Object.assign({
output: options.outputOptions,
watch: WATCH_OPTS
}, options.inputOptions)).on('event', e => {
if (e.code==='ERROR' || e.code==='FATAL') {
return reject(e);
}
if (e.code==='END') {
getSizeInfo(options._code, options.outputOptions.file).then( text => {
process.stdout.write(`Wrote ${text.trim()}\n`);
});
if (typeof onBuild=='function') {
onBuild(e);
}
}
});
});
});
}
```
---
``` js
let cache;
let out = await series(steps.map( ({ inputOptions, outputOptions }) => async () => {
inputOptions.cache = cache;
let bundle = await rollup(inputOptions); // 入口配置
cache = bundle;
await bundle.write(outputOptions); // 写 输出
return await getSizeInfo(bundle._code, outputOptions.file);
// 显示-文件大小, 并返回-颜色字符
}));
return chalk.blue(`Build output to ${relative(cwd, dirname(options.output)) || '.'}:`) + '\n ' + out.join('\n ');
// 颜色记录
}
```