feat: centralized build
This commit is contained in:
parent
dfbe25624e
commit
89ccd8148b
7
packages/build/.gitignore
vendored
Normal file
7
packages/build/.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
**/*.js
|
||||||
|
**/*.map
|
||||||
|
!/.*
|
||||||
|
!/.neutrinorc.js
|
||||||
|
!/webpack.config.js
|
||||||
|
!src/**/*.js
|
||||||
|
!/test/**/*.js
|
39
packages/build/.neutrinorc.js
Normal file
39
packages/build/.neutrinorc.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
const {chmod} = require('fs');
|
||||||
|
const {join} = require('path');
|
||||||
|
|
||||||
|
const banner = require('@neutrinojs/banner');
|
||||||
|
const copy = require('@neutrinojs/copy');
|
||||||
|
|
||||||
|
module.exports = require('./src/build/.neutrinorc');
|
||||||
|
|
||||||
|
module.exports.use.push(banner({
|
||||||
|
banner: '#!/usr/bin/env node',
|
||||||
|
raw: true,
|
||||||
|
pluginId: 'shebang',
|
||||||
|
}))
|
||||||
|
|
||||||
|
module.exports.use.push(({config}) => {
|
||||||
|
config
|
||||||
|
.plugin('executable')
|
||||||
|
.use(class Executable {
|
||||||
|
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.afterEmit.tapAsync(
|
||||||
|
'Executable',
|
||||||
|
(compilation, callback) => {
|
||||||
|
chmod(join(__dirname, 'build.js'), 0o755, callback);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports.use.push(
|
||||||
|
copy({
|
||||||
|
patterns: [{
|
||||||
|
from: 'src/build',
|
||||||
|
to: 'build',
|
||||||
|
}],
|
||||||
|
}),
|
||||||
|
);
|
41
packages/build/package.json
Normal file
41
packages/build/package.json
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"name": "@latus/build",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"author": "cha0s",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"latus-build": "./build.js"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "NODE_PATH=./node_modules webpack --config ./webpack.config.js --mode production",
|
||||||
|
"clean": "rm -rf yarn.lock node_modules/* $(node -e \"process.stdout.write(require('./package.json').files.filter((file) => {const parts = file.split('/'); return 1 === parts.length || 'test' !== parts[0];}).join(' '));\")",
|
||||||
|
"forcepub": "npm unpublish --force $(node -e 'const {name, version} = require(`./package.json`); process.stdout.write(`${name}@${version}`)') && npm publish",
|
||||||
|
"lint": "NODE_PATH=./node_modules eslint --config ./.eslintrc.js --format codeframe --ext mjs,js .",
|
||||||
|
"test": "yarn --silent run build --display none && mocha --colors test.js"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"build",
|
||||||
|
"build.js",
|
||||||
|
"index.js",
|
||||||
|
"index.js.map",
|
||||||
|
"test.js",
|
||||||
|
"test.js.map"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"@neutrinojs/airbnb": "^9.4.0",
|
||||||
|
"@neutrinojs/banner": "^9.4.0",
|
||||||
|
"@neutrinojs/copy": "^9.4.0",
|
||||||
|
"@neutrinojs/mocha": "^9.4.0",
|
||||||
|
"chai": "4.2.0",
|
||||||
|
"commander": "^7.1.0",
|
||||||
|
"eslint": "^7",
|
||||||
|
"eslint-import-resolver-webpack": "0.13.0",
|
||||||
|
"mocha": "^8",
|
||||||
|
"neutrino": "^9.4.0",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"source-map-support": "0.5.19",
|
||||||
|
"webpack": "^4",
|
||||||
|
"webpack-cli": "^3"
|
||||||
|
}
|
||||||
|
}
|
181
packages/build/src/build.js
Executable file
181
packages/build/src/build.js
Executable file
|
@ -0,0 +1,181 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
import {spawn} from 'child_process';
|
||||||
|
import {statSync} from 'fs';
|
||||||
|
import {join, normalize} from 'path';
|
||||||
|
|
||||||
|
import {Command} from 'commander';
|
||||||
|
import rimraf from 'rimraf';
|
||||||
|
|
||||||
|
const program = new Command();
|
||||||
|
|
||||||
|
const cwd = normalize(process.cwd());
|
||||||
|
|
||||||
|
const localConfig = (filename) => {
|
||||||
|
let configFile = join(__dirname, 'build', filename);
|
||||||
|
try {
|
||||||
|
const localConfig = join(cwd, filename);
|
||||||
|
statSync(localConfig);
|
||||||
|
configFile = localConfig;
|
||||||
|
}
|
||||||
|
catch (error) {}
|
||||||
|
return configFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
const build = async (args = []) => {
|
||||||
|
const {production} = program.opts();
|
||||||
|
const configFile = localConfig('webpack.config.js');
|
||||||
|
const child = spawn(
|
||||||
|
'webpack',
|
||||||
|
[
|
||||||
|
'--config',
|
||||||
|
configFile,
|
||||||
|
'--mode',
|
||||||
|
production ? 'production' : 'development',
|
||||||
|
]
|
||||||
|
.concat(args),
|
||||||
|
{
|
||||||
|
env: {
|
||||||
|
NODE_PATH: './node_modules',
|
||||||
|
...process.env,
|
||||||
|
},
|
||||||
|
stdio: 'inherit',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
child.on('error', reject);
|
||||||
|
child.on('exit', (code) => {
|
||||||
|
child.off('error', reject);
|
||||||
|
resolve(code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('build', {isDefault: true})
|
||||||
|
.description('build package')
|
||||||
|
.action(() => build());
|
||||||
|
|
||||||
|
const clean = () => {
|
||||||
|
rimraf.sync(join(cwd, 'node_modules', '*'));
|
||||||
|
rimraf.sync(join(cwd, 'yarn.lock'));
|
||||||
|
const {files} = __non_webpack_require__(join(cwd, 'package.json'));
|
||||||
|
rimraf.sync(
|
||||||
|
files
|
||||||
|
.map((filename) => join(cwd, filename))
|
||||||
|
.join(' '),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('clean')
|
||||||
|
.description('remove node_modules/*, yarn.lock, and build artifacts')
|
||||||
|
.action(clean);
|
||||||
|
|
||||||
|
const unpublish = async () => {
|
||||||
|
const {name, version} = __non_webpack_require__(join(cwd, 'package.json'));
|
||||||
|
const child = spawn(
|
||||||
|
'npm',
|
||||||
|
[
|
||||||
|
'unpublish',
|
||||||
|
'--force',
|
||||||
|
`${name}@${version}`,
|
||||||
|
],
|
||||||
|
{
|
||||||
|
stdio: 'inherit',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
child.on('error', reject);
|
||||||
|
child.on('exit', (code) => {
|
||||||
|
child.off('error', reject);
|
||||||
|
resolve(code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const publish = async () => {
|
||||||
|
const child = spawn(
|
||||||
|
'npm',
|
||||||
|
[
|
||||||
|
'publish',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
stdio: 'inherit',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
child.on('error', reject);
|
||||||
|
child.on('exit', (code) => {
|
||||||
|
child.off('error', reject);
|
||||||
|
resolve(code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('forcepublish')
|
||||||
|
.alias('fp')
|
||||||
|
.description('force publish to npm')
|
||||||
|
.action(async () => {
|
||||||
|
await unpublish();
|
||||||
|
await publish();
|
||||||
|
});
|
||||||
|
|
||||||
|
const lint = () => {
|
||||||
|
const {production} = program.opts();
|
||||||
|
const configFile = localConfig('.eslintrc.js');
|
||||||
|
spawn(
|
||||||
|
'eslint',
|
||||||
|
[
|
||||||
|
'--config',
|
||||||
|
configFile,
|
||||||
|
'--format',
|
||||||
|
'codeframe',
|
||||||
|
'--ext',
|
||||||
|
'mjs,js',
|
||||||
|
'.',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
env: {
|
||||||
|
NODE_PATH: './node_modules',
|
||||||
|
...process.env,
|
||||||
|
},
|
||||||
|
stdio: 'inherit',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('lint')
|
||||||
|
.description('run linter')
|
||||||
|
.action(lint);
|
||||||
|
|
||||||
|
const test = async () => {
|
||||||
|
await build(['--display', 'none']);
|
||||||
|
const {production} = program.opts();
|
||||||
|
const configFile = localConfig('.eslintrc.js');
|
||||||
|
spawn(
|
||||||
|
'mocha',
|
||||||
|
[
|
||||||
|
'--colors',
|
||||||
|
'test.js',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
env: {
|
||||||
|
NODE_PATH: './node_modules',
|
||||||
|
...process.env,
|
||||||
|
},
|
||||||
|
stdio: 'inherit',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('test')
|
||||||
|
.description('build and run tests')
|
||||||
|
.action(test);
|
||||||
|
|
||||||
|
program
|
||||||
|
.option('-d, --no-production', 'dev build');
|
||||||
|
|
||||||
|
program.parse(process.argv);
|
23
packages/build/src/build/.eslint.defaults.js
Normal file
23
packages/build/src/build/.eslint.defaults.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
const config = {
|
||||||
|
globals: {
|
||||||
|
__non_webpack_require__: true,
|
||||||
|
process: true,
|
||||||
|
window: true,
|
||||||
|
},
|
||||||
|
ignorePatterns: [
|
||||||
|
'/*',
|
||||||
|
'!/src',
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
'babel/object-curly-spacing': 'off',
|
||||||
|
'brace-style': ['error', 'stroustrup'],
|
||||||
|
'no-bitwise': ['error', {int32Hint: true}],
|
||||||
|
'no-plusplus': 'off',
|
||||||
|
'no-shadow': 'off',
|
||||||
|
'no-underscore-dangle': 'off',
|
||||||
|
'padded-blocks': ['error', {classes: 'always'}],
|
||||||
|
yoda: 'off',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = config;
|
3
packages/build/src/build/.eslintrc.js
Normal file
3
packages/build/src/build/.eslintrc.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const neutrino = require('neutrino');
|
||||||
|
|
||||||
|
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).eslintrc();
|
108
packages/build/src/build/.neutrinorc.js
Normal file
108
packages/build/src/build/.neutrinorc.js
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
const {basename, dirname, extname, join} = require('path');
|
||||||
|
|
||||||
|
const airbnb = require('@neutrinojs/airbnb');
|
||||||
|
const glob = require('glob');
|
||||||
|
const mocha = require('@neutrinojs/mocha');
|
||||||
|
const react = require('@neutrinojs/react');
|
||||||
|
const nodeExternals = require('webpack-node-externals');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
options: {},
|
||||||
|
use: [
|
||||||
|
airbnb({
|
||||||
|
eslint: {
|
||||||
|
cache: false,
|
||||||
|
baseConfig: require(`${__dirname}/.eslint.defaults`),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
(neutrino) => {
|
||||||
|
const {files = [], name} = neutrino.options.packageJson;
|
||||||
|
files
|
||||||
|
.filter((file) => {
|
||||||
|
const {source} = neutrino.options;
|
||||||
|
try {
|
||||||
|
require.resolve(`${source}/${file}`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
const ext = extname(file);
|
||||||
|
try {
|
||||||
|
require.resolve(`${source}/${dirname(file)}/${basename(file, ext)}/index${ext}`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.forEach((file) => {
|
||||||
|
const isIndex = 'index.js' === file;
|
||||||
|
const trimmed = join(dirname(file), basename(file, extname(file)));
|
||||||
|
neutrino.options.mains[trimmed] = {entry: isIndex ? file : `./src/${trimmed}`};
|
||||||
|
});
|
||||||
|
const testPaths = glob.sync('./test/*.js');
|
||||||
|
if (testPaths.length > 0) {
|
||||||
|
const testEntry = neutrino.config.entry('test').clear();
|
||||||
|
testPaths.forEach((path) => testEntry.add(path));
|
||||||
|
}
|
||||||
|
const cssPaths = glob.sync('./src/**/*.{css,scss}');
|
||||||
|
if (cssPaths.length > 0) {
|
||||||
|
const cssEntry = neutrino.config.entry('index.css').clear();
|
||||||
|
cssPaths.forEach((path) => cssEntry.add(path));
|
||||||
|
}
|
||||||
|
neutrino.options.output = '.';
|
||||||
|
react({
|
||||||
|
clean: false,
|
||||||
|
hot: false,
|
||||||
|
style: {
|
||||||
|
extract: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
test: /\.(css|sass|scss)$/,
|
||||||
|
modulesTest: /\.module\.(css|sass|scss)$/,
|
||||||
|
loaders: [
|
||||||
|
{
|
||||||
|
loader: 'postcss-loader',
|
||||||
|
useId: 'postcss',
|
||||||
|
options: {
|
||||||
|
config: {
|
||||||
|
path: process.cwd(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: 'sass-loader',
|
||||||
|
useId: 'sass',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})(neutrino);
|
||||||
|
Object.keys(neutrino.options.mains).forEach((main) => {
|
||||||
|
neutrino.config.plugins.delete(`html-${main}`);
|
||||||
|
});
|
||||||
|
neutrino.config
|
||||||
|
.devtool('source-map')
|
||||||
|
.target('node')
|
||||||
|
.optimization
|
||||||
|
.splitChunks(false)
|
||||||
|
.runtimeChunk(false)
|
||||||
|
.end()
|
||||||
|
.output
|
||||||
|
.filename('[name].js')
|
||||||
|
.library(name)
|
||||||
|
.libraryTarget('umd')
|
||||||
|
.umdNamedDefine(true)
|
||||||
|
.end()
|
||||||
|
.node
|
||||||
|
.set('__dirname', false)
|
||||||
|
.set('__filename', false);
|
||||||
|
const options = neutrino.config.module
|
||||||
|
.rule('compile')
|
||||||
|
.use('babel')
|
||||||
|
.get('options');
|
||||||
|
options.presets[0][1].targets = {esmodules: true};
|
||||||
|
neutrino.config.externals(nodeExternals({importType: 'umd'}));
|
||||||
|
},
|
||||||
|
mocha(),
|
||||||
|
],
|
||||||
|
};
|
6
packages/build/src/build/postcss.config.js
Normal file
6
packages/build/src/build/postcss.config.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/* eslint-disable global-require */
|
||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
require('autoprefixer'),
|
||||||
|
],
|
||||||
|
};
|
3
packages/build/src/build/webpack.config.js
Normal file
3
packages/build/src/build/webpack.config.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const neutrino = require('neutrino');
|
||||||
|
|
||||||
|
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).webpack();
|
0
packages/build/src/index.js
Normal file
0
packages/build/src/index.js
Normal file
5
packages/build/test/exists.js
Normal file
5
packages/build/test/exists.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import {expect} from 'chai';
|
||||||
|
|
||||||
|
it('exists', () => {
|
||||||
|
expect(true).to.be.true;
|
||||||
|
});
|
3
packages/build/webpack.config.js
Normal file
3
packages/build/webpack.config.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const neutrino = require('neutrino');
|
||||||
|
|
||||||
|
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).webpack();
|
4727
packages/build/yarn.lock
Normal file
4727
packages/build/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user