Skip to content

Commit

Permalink
rollup build bundles to support umd and esm
Browse files Browse the repository at this point in the history
  • Loading branch information
cancerberoSgx committed Nov 17, 2018
1 parent c79515e commit 99ab0c8
Show file tree
Hide file tree
Showing 13 changed files with 944 additions and 20 deletions.
635 changes: 633 additions & 2 deletions package-lock.json

Large diffs are not rendered by default.

28 changes: 19 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,30 @@
"name": "wasm-imagemagick",
"version": "1.1.1",
"description": "Webassembly compilation of ImageMagick",

"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts",
"module": "dist/esm5/index.js",
"es2015": "dist/esm2018/index.js",

"scripts": {
"build-wasm": "docker build -t wasm-imagemagick-build-tools . && docker run --rm --workdir /code -v \"$PWD\":/code wasm-imagemagick-build-tools bash ./build.sh",
"build-ts": "tsc",
"build-ts": "rm -rf dist && tsc && npm run bundle",
"bundle": "npx tsc --project tsconfig-esm5.json && npx tsc --project tsconfig-es2018.json && npx rollup -c rollup.config.js && npx rollup -c rollup.config.js --environment NODE_ENV:production",
"build": "npm run build-wasm && npm run build-ts",
"prepare": "npm run build && npm run copy && npm run magickApiJs",
"copy": "cp magick.js magick.wasm dist && cp magick.js magick.wasm spec/assets && cp -r spec/assets dist",
"magickApiJs": "tsc src/magickApi.ts --lib dom,es6 --target es2018 --outdir .",
"magickApiJs": "cp dist/bundles/index.esm.js magickApi.js",
"clean": "sh clean.sh",

"lint": "tslint \"src/**/*.ts\" \"spec/**/*.ts\"",
"lint-and-fix": "tslint \"src/**/*.ts\" \"spec/**/*.ts\" --fix",
"generateImEnums": "npx ts-node scripts/generateImEnums.ts",

"test": "npm run test-node && npm run test-browser",
"test-node": "cd tests/rotate && node node",

"test-browser-build": "tsc && browserify -d dist/spec/index.js -o dist/bundle.js",
"test-browser": "rm -rf dist && npm run test-browser-build && npm run copy && gulp --gulpfile spec/gulpfile.js jasmine",
"test-browser-server": "rm -rf dist && npm run test-browser-build && npm run copy && gulp --gulpfile spec/gulpfile.js jasmine-server",
"test-browser-build": "npm run build-ts && browserify -d dist/spec/index.js -o dist/bundle.js",

"test-browser-start": "rm -rf dist && npm run build-ts && npm run copy && npm run test-browser-watch-all",
"test-browser-start": "rm -rf dist && tsc && npm run copy && npm run test-browser-watch-all",
"test-browser-watch-all": "concurrently 'npm run test-browser-watch-build' 'npm run test-browser-watch-server' ",
"test-browser-watch-build": "onchange -i -v 'src/**/*' 'spec/**/*' -- npm run test-browser-build",
"test-browser-watch-server": "onchange -k -v 'dist/bundle.js' -- gulp --gulpfile spec/gulpfile.js jasmine-server"
Expand Down Expand Up @@ -58,11 +59,20 @@
"jasmine": "^3.3.0",
"onchange": "^5.1.0",
"puppeteer": "^1.3.0",
"rollup": "0.66.6",
"rollup-plugin-commonjs": "9.2.0",
"rollup-plugin-json": "3.1.0",
"rollup-plugin-node-resolve": "3.4.0",
"rollup-plugin-replace": "2.1.0",
"rollup-plugin-sourcemaps": "0.4.2",
"rollup-plugin-terser": "3.0.0",
"rollup-plugin-uglify-es": "0.0.1",
"shelljs": "^0.8.3",
"ts-node": "^7.0.1",
"ts-simple-ast": "^19.0.0",
"tslint": "^5.11.0",
"typescript": "^3.1.6"
"typescript": "^3.1.6",
"webpack-config-utils": "^2.3.1"
},
"dependencies": {
"p-map": "^2.0.0"
Expand Down
129 changes: 129 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { resolve } from 'path'
import sourceMaps from 'rollup-plugin-sourcemaps'
import nodeResolve from 'rollup-plugin-node-resolve'
import json from 'rollup-plugin-json'
import commonjs from 'rollup-plugin-commonjs'
import replace from 'rollup-plugin-replace'
import uglify from 'rollup-plugin-uglify-es'
import { terser } from 'rollup-plugin-terser'
import { getIfUtils, removeEmpty } from 'webpack-config-utils'

import pkg from './package.json'

const env = process.env.NODE_ENV || 'development'
const { ifProduction } = getIfUtils(env)

const LIB_NAME = pascalCase(normalizePackageName(pkg.name))
const ROOT = resolve(__dirname, '.')
const DIST = resolve(ROOT, 'dist')

/**
* Object literals are open-ended for js checking, so we need to be explicit
*/
const PATHS = {
entry: {
esm5: resolve(DIST, 'esm5'),
esm2018: resolve(DIST, 'esm2018'),
},
bundles: resolve(DIST, 'bundles'),
}


// helpers

function dashToCamelCase(myStr) {
return myStr.replace(/-([a-z])/g, (g) => g[1].toUpperCase())
}

function toUpperCase(myStr) {
return `${myStr.charAt(0).toUpperCase()}${myStr.substr(1)}`
}

function pascalCase(myStr) {
return toUpperCase(dashToCamelCase(myStr))
}

function normalizePackageName(rawPackageName) {
const scopeEnd = rawPackageName.indexOf('/') + 1

return rawPackageName.substring(scopeEnd)
}

function getOutputFileName(fileName, isProd = false) {
return isProd ? fileName.replace(/\.js$/, '.min.js') : fileName
}





const external = Object.keys(pkg.peerDependencies||{}) || []

const plugins = ([
// Allow json resolution
json(),

// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
commonjs(),

// Allow node_modules resolution, so you can use 'external' to control
// which external modules to include in the bundle
// https://github.com/rollup/rollup-plugin-node-resolve#usage
nodeResolve(),

// Resolve source maps to the original source
sourceMaps(),

// properly set process.env.NODE_ENV within `./environment.ts`
replace({
exclude: 'node_modules/**',
'process.env.NODE_ENV': JSON.stringify(env),
}),
])

const CommonConfig = {
input: {},
output: {},
inlineDynamicImports: true,
// Indicate here external modules you don't wanna include in your bundle (i.e.: 'lodash')
external,
}

const UMDconfig = {
...CommonConfig,
input: resolve(PATHS.entry.esm5, 'index.js'),
output: {
file: getOutputFileName(
resolve(PATHS.bundles, `${LIB_NAME}.umd-es5.js`),
ifProduction()
),
format: 'umd',
name: LIB_NAME,
sourcemap: true,
},
plugins: removeEmpty(([...plugins, ifProduction(uglify())])
),
}

const FESMconfig = {
...CommonConfig,
input: resolve(PATHS.entry.esm2018, 'index.js'),
output: [
{
file: getOutputFileName(
resolve(PATHS.bundles, `${LIB_NAME}.esm-es2018.js`),
ifProduction()
),
format: 'es',
sourcemap: true,
},
],
plugins: removeEmpty(
([...plugins, ifProduction(terser())])
),
}

export default [UMDconfig
, FESMconfig
]

38 changes: 37 additions & 1 deletion samples/interactive-execute-context/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions src/execute.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MagickInputFile, MagickOutputFile, outputFileToInputFile, call, asCommand } from '.'
import pMap from 'p-map'
import { CallResult } from './magickApi'
import { values } from './util/misc';
import { values } from './util/misc'

export type Command = (string | number)[]

Expand Down Expand Up @@ -56,13 +56,13 @@ export function asExecuteConfig(arg: ExecuteConfig | ExecuteCommand): ExecuteCon
return arg
}
return {
inputFiles: [],
inputFiles: [],
commands: arg,
}
}
/**
* Assumes the command won't fail so returns one output file directly or undefined if it's not found (or error occurs)
* @param configOrCommand
* @param configOrCommand
* @param outputFileName optionally user can give the desired output file name
*/
export async function executeAndReturnOutputFile(configOrCommand: ExecuteConfig | ExecuteCommand, outputFileName?: string): Promise<MagickOutputFile | undefined> {
Expand Down Expand Up @@ -171,4 +171,3 @@ export async function execute(configOrCommand: ExecuteConfig | ExecuteCommand):
exitCode: resultWithError ? resultWithError.exitCode : 0,
}
}

2 changes: 1 addition & 1 deletion src/imageHome.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MagickInputFile, MagickFile, asInputFile, getBuiltInImages } from '.'
import pMap from 'p-map'
import { values } from './util/misc';
import { values } from './util/misc'

export interface ImageHome {
remove(names: string[]): MagickInputFile[]
Expand Down
2 changes: 1 addition & 1 deletion src/util/cli.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Command } from '..'
import { ExecuteCommand } from '../execute'
import { flat } from './misc';
import { flat } from './misc'

/** generates a valid command line command from given Call/execute Command. Works in a single command */
export function arrayToCliOne(command: Command): string {
Expand Down
1 change: 0 additions & 1 deletion src/util/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export function values<T>(object: { [k: string]: T }): T[] {
return Object.keys(object).map(name => object[name])
}


export function flat<T>(arr: T[][]): T[] {
return arr.reduce((a, b) => a.concat(b))
}
79 changes: 79 additions & 0 deletions tests/bundles/esm-test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>test dist/bundles/index.esm.js</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
<style>
textarea{
width: 100%;
height: 250px;
}
input{
width: 100%
}
</style>

<h1>Testing /dist/bundles/index.esm.js import directly from html page </h1>
<div>
<p>Image URL: </p>
<input id="imageUrl" type="text" value="../rotate/FriedrichNietzsche.png">
</div>
<div>
<p>Commands. </p>
<textarea id="commandText">
convert FriedrichNietzsche.png -rotate 33 -resize 100x90! out.png
convert out.png -charcoal 1 charcoal1.gif
convert out.png -charcoal 2 charcoal2.gif
convert \
charcoal1.gif \
\( \
-clone 0 charcoal2.gif -compose difference \
-composite -threshold 5% -fill red \
-opaque white -transparent black \
\) \
-compose over -composite \
pcharcoaldiff.png
</textarea>
</div>

<button id="execute">Execute</button>

<div id="imagesContainer"></div>
<script type="module">

// import { execute, loadImageElement, buildInputFile } from '../../dist/bundles/index.esm.js'
import { execute, loadImageElement, buildInputFile } from '../../dist/bundles/index.esm.js'

async function renderImages(images) {
document.querySelector('#imagesContainer').innerHTML = ''
images.forEach(async imageFile => {
const container = document.createElement('div')
container.innerText = `"${imageFile.name}" : `
const img = document.createElement('img')
img.alt = img.title = imageFile.name
container.appendChild(img)
document.querySelector('#imagesContainer').appendChild(container)
await loadImageElement(imageFile, img)
})
}

export async function main() {
const input = await buildInputFile(document.querySelector('#imageUrl').value)
const commands = document.querySelector('#commandText').value
const result = await execute({ inputFiles: [input], commands })
await renderImages([input].concat(result.outputFiles))
}

document.querySelector('#execute').addEventListener('click', main)

main()
</script>
</body>

</html>
7 changes: 7 additions & 0 deletions tsconfig-es2018.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig-esm5.json",
"compilerOptions": {
"target": "es2018",
"outDir": "dist/esm2018"
}
}
Loading

0 comments on commit 99ab0c8

Please sign in to comment.