You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte/src/cli/compile.ts

140 lines
3.2 KiB

import * as path from 'path';
import * as fs from 'fs';
import * as svelte from 'svelte';
import error from './error.js';
function mkdirp(dir) {
const parent = path.dirname(dir);
if (dir === parent) return;
mkdirp(parent);
if (!fs.existsSync(dir)) fs.mkdirSync(dir);
}
export function compile(input, opts) {
if (opts._.length > 0) {
error(`Can only compile a single file or directory`);
}
const output = opts.output;
const stats = fs.statSync(input);
const isDir = stats.isDirectory();
if (isDir) {
if (!output) {
error(`You must specify an --output (-o) option when compiling a directory of files`);
}
if (opts.name || opts.amdId) {
error(`Cannot specify --${opts.name ? 'name' : 'amdId'} when compiling a directory`);
}
}
const globals = {};
if (opts.globals) {
opts.globals.split(',').forEach(pair => {
const [key, value] = pair.split(':');
globals[key] = value;
});
}
const options = {
name: opts.name,
format: opts.format,
sourceMap: opts.sourcemap,
globals,
css: opts.css !== false,
dev: opts.dev,
immutable: opts.immutable,
generate: opts.generate || 'dom',
customElement: opts.customElement,
store: opts.store
};
if (isDir) {
mkdirp(output);
compileDirectory(input, output, options);
} else {
compileFile(input, output, options);
}
}
function compileDirectory(input, output, options) {
fs.readdirSync(input).forEach(file => {
const src = path.resolve(input, file);
const dest = path.resolve(output, file);
if (path.extname(file) === '.html') {
compileFile(
src,
dest.substring(0, dest.lastIndexOf('.html')) + '.js',
options
);
} else {
const stats = fs.statSync(src);
if (stats.isDirectory()) {
compileDirectory(src, dest, options);
}
}
});
}
let SOURCEMAPPING_URL = 'sourceMa';
SOURCEMAPPING_URL += 'ppingURL';
function compileFile(input, output, options) {
console.error(`compiling ${path.relative(process.cwd(), input)}...`); // eslint-disable-line no-console
options = Object.assign({}, options);
if (!options.name) options.name = getName(input);
options.filename = input;
options.outputFilename = output;
const { sourceMap } = options;
const inline = sourceMap === 'inline';
let source = fs.readFileSync(input, 'utf-8');
if (source[0] === 0xfeff) source = source.slice(1);
let compiled;
try {
compiled = svelte.compile(source, options);
} catch (err) {
error(err);
}
const { js } = compiled;
if (sourceMap) {
js.code += `\n//# ${SOURCEMAPPING_URL}=${inline || !output
? js.map.toUrl()
: `${path.basename(output)}.map`}\n`;
}
if (output) {
const outputDir = path.dirname(output);
mkdirp(outputDir);
fs.writeFileSync(output, js.code);
console.error(`wrote ${path.relative(process.cwd(), output)}`); // eslint-disable-line no-console
if (sourceMap && !inline) {
fs.writeFileSync(`${output}.map`, js.map);
console.error(`wrote ${path.relative(process.cwd(), `${output}.map`)}`); // eslint-disable-line no-console
}
} else {
process.stdout.write(js.code);
}
}
function getName(input) {
return path
.basename(input)
.replace(path.extname(input), '')
.replace(/[^a-zA-Z_$0-9]+/g, '_')
.replace(/^_/, '')
.replace(/_$/, '')
.replace(/^(\d)/, '_$1');
}