Skip to content

Commit

Permalink
feat: Support custom loader.
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Sep 19, 2019
1 parent 13d280d commit f722667
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 257 deletions.
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
],
"jest": {},
"license": "MIT",
"files": [
"lib",
"src"
],
"devDependencies": {
"@types/case-sensitive-paths-webpack-plugin": "^2.1.3",
"@types/detect-port": "^1.1.0",
Expand Down Expand Up @@ -68,13 +72,11 @@
"eslint-loader": "^3.0.0",
"file-loader": "^4.2.0",
"fs-extra": "^8.1.0",
"html-webpack-plugin": "^3.2.0",
"html-webpack-plugin": "^4.0.0-beta.8",
"identity-obj-proxy": "^3.0.0",
"is-wsl": "^2.1.0",
"jest": "^24.9.0",
"jest-watch-typeahead": "^0.4.0",
"less": "^3.10.3",
"less-loader": "^5.0.0",
"mini-css-extract-plugin": "^0.8.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"pnp-webpack-plugin": "^1.5.0",
Expand All @@ -86,7 +88,6 @@
"react-dev-utils": "^9.0.3",
"resolve": "^1.12.0",
"resolve-url-loader": "^3.1.0",
"sass-loader": "^8.0.0",
"style-loader": "^1.0.0",
"terser-webpack-plugin": "^1.4.1",
"ts-pnp": "^1.1.4",
Expand Down
5 changes: 5 additions & 0 deletions src/command/start/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ export function builder(yarg: IMyYargsArgs) {
describe: 'Empty the DIST directory before compiling.',
default: true,
},
port: {
describe: 'port.',
type: Number,
default: 19870
}
})
.example(`$ ${color.green('kkt')} start `, 'Runs the app in development mode.')
.example(`$ ${color.green('kkt')} start --emptyDir`, 'Build your project.');
Expand Down
18 changes: 6 additions & 12 deletions src/command/start/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export default async function (args: IMyYargsArgs) {
try {
await checkBrowsers(paths.appPath, isInteractive);
const PORT = await choosePort(HOST, DEFAULT_PORT);
args.host = HOST;
args.port = PORT;
const config = await configFactory('development', args);
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const appName = require(paths.appPackageJson as string).name;
Expand All @@ -73,22 +75,14 @@ export default async function (args: IMyYargsArgs) {
useTypeScript,
webpack,
});
// Load proxy config
const proxySetting = require(paths.appPackageJson as string).proxy;
const proxyConfig = prepareProxy(proxySetting, paths.appPublic as string);
// Serve webpack assets generated by the compiler over a web server.
const serverConfig = createDevServerConfig(
proxyConfig,
urls.lanUrlForConfig
);
const devServer = new WebpackDevServer(compiler, serverConfig as WebpackDevServer.Configuration);
const devServer = new WebpackDevServer(compiler, config.devServer as WebpackDevServer.Configuration);
// Launch WebpackDevServer.
devServer.listen(PORT, HOST, err => {
if (err) {
return console.log(err);
}
if (isInteractive) {
clearConsole();
// clearConsole();
}

// We used to support resolving modules according to `NODE_PATH`.
Expand All @@ -104,13 +98,13 @@ export default async function (args: IMyYargsArgs) {
}

console.log(color.cyan('Starting the development server...\n'));
openBrowser(urls.localUrlForBrowser);
// openBrowser(urls.localUrlForBrowser);
});

['SIGINT', 'SIGTERM'].forEach((sig) => {
process.on(sig as NodeJS.Signals, () => {
devServer.close();
process.exit();
// process.exit();
});
});
} catch (error) {
Expand Down
9 changes: 9 additions & 0 deletions src/config/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default (options: JestConfOptions) => {
'coverageThreshold',
'globals',
'mapCoverage',
'maxWorkers',
'moduleFileExtensions',
'moduleNameMapper',
'modulePaths',
Expand All @@ -29,6 +30,14 @@ export default (options: JestConfOptions) => {
'reporters',
];
const conf: Config.InitialOptions = {
/**
* Specifies the maximum number of workers the
* worker-pool will spawn for running tests. This
* defaults to the number of the cores available
* on your machine. (its usually best not to
* override this default) [number]
*/
maxWorkers: 1,
"roots": [
"<rootDir>/src"
],
Expand Down
4 changes: 2 additions & 2 deletions src/config/webpack.config.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default (proxy: WebpackDevServer.ProxyConfigArrayItem[], allowedHost: str
compress: true,
// Silence WebpackDevServer's own logs since they're generally not useful.
// It will still show compile warnings and errors with this setting.
clientLogLevel: 'none',
// clientLogLevel: 'none',
// By default WebpackDevServer serves physical files from current directory
// in addition to all the virtual build products that it serves from memory.
// This is confusing because those files won’t automatically be available in
Expand Down Expand Up @@ -78,7 +78,7 @@ export default (proxy: WebpackDevServer.ProxyConfigArrayItem[], allowedHost: str
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebook/create-react-app/issues/387.
disableDotRule: true,
// disableDotRule: true,
},
public: allowedHost,
proxy,
Expand Down
50 changes: 42 additions & 8 deletions src/config/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,52 @@ export default async (env: string = 'development', args?: IMyYargsArgs) => {

conf = require('../plugs/optimization')(conf, optionConf);
conf = require('../plugs/resolve')(conf, optionConf);
conf = require('../plugs/eslint-loader')(conf, optionConf);
/**
* Add loader
* ============================
*/
conf.module.rules = [...(require('../plugs/eslint-loader')(conf, optionConf))];
// console.log('conf.module.rules:', conf.module.rules);
const kktConf = await loadConfHandle(paths.appKKTRC);
let loaderDefault: { [key: string]: any } = {
url: require('../plugs/url-loader'),
babel: require('../plugs/babel-loader'),
css: require('../plugs/css-loader'),
file: require('../plugs/file-loader'),
}
if (kktConf && kktConf.loaderDefault && typeof kktConf.loaderDefault === 'function') {
let loaderConf = kktConf.loaderDefault(loaderDefault, conf, optionConf);
if (loaderConf) loaderDefault = loaderConf;
}

let loaderOneOf: any[] = [];
if (kktConf && kktConf.loaderOneOf && Array.isArray(kktConf.loaderOneOf)) {
loaderOneOf = await Promise.all(kktConf.loaderOneOf.map(async (item: any) => {
return Array.isArray(item) ? (await require(item[0])(conf, optionConf, item[1] ? item[1] : {}))
: (await require(item)(conf, optionConf, {}));
}));
}
const defaultLoader = await Promise.all(Object.keys(loaderDefault).map(async (keyName) => {
if (loaderDefault[keyName] && typeof loaderDefault[keyName] == 'function') {
return await loaderDefault[keyName](conf, optionConf);
}
}));
let loader: any[] = [];
[...loaderOneOf, ...defaultLoader].filter(Boolean).forEach((item) => {
loader = loader.concat(item);
});
// "oneOf" will traverse all following loaders until one will
// match the requirements. When no loader matches it will fall
// back to the "file" loader at the end of the loader list.
conf.module.rules.push({ oneOf: [] });
conf = require('../plugs/url-loader')(conf, optionConf);
conf = require('../plugs/babel-loader')(conf, optionConf);
conf = require('../plugs/css-loader')(conf, optionConf);
conf = require('../plugs/file-loader')(conf, optionConf);
conf.module.rules.push({ oneOf: [...loader] });

// Use webpack plugins.
conf = require('../plugs/plugins')(conf, optionConf);
const kktConf = await loadConfHandle(paths.appKKTRC);
conf = (kktConf.default || kktConf)(conf, optionConf) || conf;
conf = require('../plugs/devServer')(conf, optionConf);

const deafultKKTConf = (kktConf.default || kktConf)
if (deafultKKTConf && typeof deafultKKTConf === 'function'){
conf = deafultKKTConf(conf, optionConf) || conf;
}
return conf;
}
126 changes: 60 additions & 66 deletions src/plugs/babel-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,71 @@ import { Configuration } from 'webpack';
import { OptionConf } from '../config/webpack.config';
import * as paths from '../config/paths';

// Process application JS with Babel.
// The preset includes JSX, Flow, TypeScript, and some ESnext features.
module.exports = (conf: Configuration, options: OptionConf) => {
conf.module.rules = conf.module.rules.map((item) => {
if (item.oneOf) {
// Process application JS with Babel.
// The preset includes JSX, Flow, TypeScript, and some ESnext features.
item.oneOf.push({
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc as string,
loader: require.resolve('babel-loader'),
options: {
presets: [
[require.resolve('@tsbb/babel-preset-tsbb'), {
targets: {
browsers: ['last 2 versions', 'ie >= 10'],
},
presetReact: true,
}]
],
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
),
plugins: [
[
require.resolve('babel-plugin-named-asset-import'),
{
loaderMap: {
svg: {
ReactComponent: '@svgr/webpack?-svgo,+titleProp,+ref![path]',
},
return [
// Process application JS with Babel.
// The preset includes JSX, Flow, TypeScript, and some ESnext features.
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc as string,
loader: require.resolve('babel-loader'),
options: {
presets: [
[require.resolve('@tsbb/babel-preset-tsbb'), {
targets: {
browsers: ['last 2 versions', 'ie >= 10'],
},
presetReact: true,
}]
],
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
),
plugins: [
[
require.resolve('babel-plugin-named-asset-import'),
{
loaderMap: {
svg: {
ReactComponent: '@svgr/webpack?-svgo,+titleProp,+ref![path]',
},
},
],
},
],
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
cacheCompression: options.isEnvProduction,
compact: options.isEnvProduction,
},
});
// Process any JS outside of the app with Babel.
// Unlike the application JS, we only compile the standard ES features.
item.oneOf.push({
test: /\.(js|mjs)$/,
exclude: /@babel(?:\/|\\{1,2})runtime/,
loader: require.resolve('babel-loader'),
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [
[
require.resolve('babel-preset-react-app/dependencies'),
{ helpers: true },
],
],
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
cacheCompression: options.isEnvProduction,
compact: options.isEnvProduction,
},
},
// Process any JS outside of the app with Babel.
// Unlike the application JS, we only compile the standard ES features.
{
test: /\.(js|mjs)$/,
exclude: /@babel(?:\/|\\{1,2})runtime/,
loader: require.resolve('babel-loader'),
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [
[
require.resolve('babel-preset-react-app/dependencies'),
{ helpers: true },
],
cacheDirectory: true,
cacheCompression: options.isEnvProduction,
],
cacheDirectory: true,
cacheCompression: options.isEnvProduction,

// If an error happens in a package, it's possible to be
// because it was compiled. Thus, we don't want the browser
// debugger to show the original code. Instead, the code
// being evaluated would be much more helpful.
sourceMaps: false,
},
});
// If an error happens in a package, it's possible to be
// because it was compiled. Thus, we don't want the browser
// debugger to show the original code. Instead, the code
// being evaluated would be much more helpful.
sourceMaps: false,
},
}
return item;
});
return conf;
];
};

0 comments on commit f722667

Please sign in to comment.