Skip to content

Commit

Permalink
add css/scss modules support, back
Browse files Browse the repository at this point in the history
  • Loading branch information
delambo committed Apr 7, 2024
1 parent c562ab9 commit 1db1da1
Show file tree
Hide file tree
Showing 23 changed files with 1,358 additions and 123 deletions.
9 changes: 9 additions & 0 deletions .mise.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[tools]
node = '20.10.0'
# stuck on this version of yarn because of some weird problems
# related to babel tooling when installing new dependencies
yarn = '1.19.0'

[env]
RTX_FETCH_REMOTE_VERSIONS_TIMEOUT="300 s"
NODE_OPTIONS = "--openssl-legacy-provider"
1 change: 0 additions & 1 deletion .nvmrc

This file was deleted.

18 changes: 16 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,25 @@ If you want to propose a large feature idea or architecture change you should co

## kyt local development

1. `nvm use`
1. Fork and clone `kyt`
1. [setup [mise](https://mise.jdx.dev/) and `mise install`]
1. Run `yarn bootstrap` to install the packages in the monorepo
1. Open a new shell and run `yarn watch`

[lerna](/~https://github.com/lerna/lerna) is used to manage the monorepo but most of the development commands should be exercised through root directory `package.json` scripts. The following are some useful npm scripts for development:
Most changes are best to develop against the universal starter kyt:

1. `cd packages/kyt-starter-universal/starter-src`
1. Run `yarn dev` or `yarn build` to test against kyt development and production builds

Note: After you make changes, the watcher will update libraries but you will likely have to restart the universal app process to test changes. The watcher only works against kyt-core/server/runtimg. Changes to babel presets and a few other packages may require you to re-`yarn bootstrap` or `yarn clean-bootstrap`. When in doubt run `yarn clean-bootstrap`.

[lerna](/~https://github.com/lerna/lerna) is used to manage the monorepo but most of the development commands should be exercised through root directory `package.json` scripts.

### dev workflow

1. open a new shell and start `yarn watch-cli`

The following are some useful npm scripts for development:

### bootstrap

Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"yarn": "^1"
},
"scripts": {
"bootstrap": "yarn && lerna run prepare",
"bootstrap": "yarn && lerna bootstrap && lerna run prepare && lerna link",
"bootstrap:ci": "yarn && lerna run prepare",
"clean-bootstrap": "lerna clean --yes && rm -rf node_modules && yarn bootstrap",
"publish": "lerna publish",
Expand All @@ -31,7 +31,10 @@
"lint-staged": "yarn run lint -o",
"lint-fix": "ESLINT_FIX=1 ESLINT_QUIET=1 yarn run lint",
"lint:ci": "ESLINT_QUIET=1 yarn run lint",
"watch-cli": "yarn workspace kyt watch",
"watch": "run-p watch-*",
"watch-kyt": "yarn workspace kyt watch",
"watch-kyt-runtime": "yarn workspace kyt-runtime watch",
"watch-kyt-utils": "yarn workspace kyt-utils watch",
"prepare": "husky install"
},
"devDependencies": {
Expand Down Expand Up @@ -62,6 +65,7 @@
"jest-runner-eslint": "0.10.1",
"jest-silent-reporter": "0.5.0",
"lerna": "4.0.0",
"npm-run-all": "4.1.5",
"prettier": "2.8.8",
"react": "17.0.2",
"react-dom": "17.0.2",
Expand Down
7 changes: 7 additions & 0 deletions packages/kyt-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"babel-preset-kyt-core": "2.0.1",
"commander": "8.2.0",
"core-js": "3.18.0",
"css-loader": "5.2.7",
"file-loader": "6.2.0",
"filesize": "8.0.3",
"find-babel-config": "1.2.0",
Expand All @@ -36,18 +37,24 @@
"kyt-utils": "1.3.33",
"lodash.clonedeep": "4.5.0",
"lodash.merge": "4.6.2",
"mini-css-extract-plugin": "1.6.2",
"optimize-css-assets-webpack-plugin": "6.0.1",
"postcss-loader": "4.2.0",
"prop-types": "15.7.2",
"ps-tree": "1.2.0",
"react": "17.0.2",
"react-dev-utils": "11.0.4",
"react-error-overlay": "6.0.9",
"regenerator-runtime": "0.13.9",
"sass": "1.74.1",
"sass-loader": "10.2.0",
"semver": "7.3.5",
"shelljs": "0.8.5",
"simple-git": "2.42.0",
"sockjs-client": "1.5.2",
"source-map-support": "0.5.20",
"strip-ansi": "6.0.0",
"style-loader": "0.23.1",
"url-loader": "4.1.1",
"webpack": "4.46.0",
"webpack-dev-server": "3.11.2",
Expand Down
5 changes: 5 additions & 0 deletions packages/kyt-core/src/config/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
postcssOptions: {
plugins: [['autoprefixer', {}]],
},
};
40 changes: 38 additions & 2 deletions packages/kyt-core/src/config/webpack.dev.client.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// Development webpack config for client code
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');
const { kytWebpackPlugins } = require('kyt-runtime/webpack');
const { clientSrcPath, assetsBuildPath, publicBuildPath } = require('kyt-utils/paths')();
const { clientSrcPath, assetsBuildPath, publicBuildPath, publicSrcPath } =
require('kyt-utils/paths')();
const getPolyfill = require('./getPolyfill');
const postcssLoader = require('../utils/getPostcssLoader');

module.exports = options => {
const main = [
Expand Down Expand Up @@ -65,6 +68,39 @@ module.exports = options => {
},
},

plugins: [...kytWebpackPlugins(options), new webpack.HotModuleReplacementPlugin()],
module: {
rules: [
{
test: /\.module\.(sc|c)ss$/,
use: [
// 'style-loader',
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]-[local]--[hash:base64:5]',
// exportOnlyLocals: true,
},
},
},
// postcssLoader,
'sass-loader',
],
exclude: [publicSrcPath],
},
],
},

plugins: [
...kytWebpackPlugins(options),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',
chunkFilename: '[id].css',
}),
new webpack.HotModuleReplacementPlugin(),
],
};
};
25 changes: 24 additions & 1 deletion packages/kyt-core/src/config/webpack.dev.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const { serverSrcPath, serverBuildPath, clientAssetsFile, loadableAssetsFile } =
const { serverSrcPath, serverBuildPath, clientAssetsFile, loadableAssetsFile, publicSrcPath } =
require('kyt-utils/paths')();
const StartServerPlugin = require('./StartServerPlugin');
const postcssLoader = require('../utils/getPostcssLoader');
const getPolyfill = require('./getPolyfill');

const nodeArgs = ['-r', 'source-map-support/register', '--max_old_space_size=4096'];
Expand Down Expand Up @@ -66,6 +67,28 @@ module.exports = options => {
libraryTarget: 'commonjs2',
},

module: {
rules: [
{
test: /\.module\.(sc|c)ss$/,
use: [
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]-[local]--[hash:base64:5]',
exportOnlyLocals: true,
},
},
},
postcssLoader,
'sass-loader',
],
exclude: [publicSrcPath],
},
],
},

plugins: [
// Prevent creating multiple chunks for the server
new webpack.optimize.LimitChunkCountPlugin({
Expand Down
44 changes: 41 additions & 3 deletions packages/kyt-core/src/config/webpack.prod.client.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Production webpack config for client code

const { clientSrcPath, assetsBuildPath } = require('kyt-utils/paths')();
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const { clientSrcPath, assetsBuildPath, publicSrcPath } = require('kyt-utils/paths')();
const { kytWebpackPlugins } = require('kyt-runtime/webpack');
const postcssLoader = require('../utils/getPostcssLoader');
const getPolyfill = require('./getPolyfill');

module.exports = options => ({
Expand All @@ -22,7 +24,43 @@ module.exports = options => ({
publicPath: options.publicPath,
},

plugins: [...kytWebpackPlugins(options)],
module: {
rules: [
{
test: /\.module\.(sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]-[local]--[hash:base64:5]',
},
},
},
postcssLoader,
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
exclude: [publicSrcPath],
},
],
},

plugins: [
...kytWebpackPlugins(options),

new MiniCssExtractPlugin({
filename: '[name]-[contenthash].css',
chunkFilename: '[name]-[contenthash].css',
}),

new OptimizeCSSAssetsPlugin({}),
],

optimization: {
moduleIds: 'hashed',
Expand Down
25 changes: 24 additions & 1 deletion packages/kyt-core/src/config/webpack.prod.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const { serverSrcPath, serverBuildPath } = require('kyt-utils/paths')();
const { serverSrcPath, serverBuildPath, publicSrcPath } = require('kyt-utils/paths')();
const postcssLoader = require('../utils/getPostcssLoader');
const getPolyfill = require('./getPolyfill');

module.exports = options => {
Expand Down Expand Up @@ -47,6 +48,28 @@ module.exports = options => {
libraryTarget: 'commonjs2',
},

module: {
rules: [
{
test: /\.module\.(sc|c)ss$/,
use: [
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]-[local]--[hash:base64:5]',
exportOnlyLocals: true,
},
},
},
postcssLoader,
'sass-loader',
],
exclude: [publicSrcPath],
},
],
},

plugins: [
new webpack.BannerPlugin({
banner: 'require("source-map-support").install();',
Expand Down
21 changes: 21 additions & 0 deletions packages/kyt-core/src/utils/getPostcssLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const fs = require('fs');
const { userPostcssConfigPath } = require('kyt-utils/paths')();
const logger = require('kyt-utils/logger');
const kytPostcssConfig = require('../config/postcss.config');

// We either use the kyt postcss.config.js or we use an
// override from the user.
const postcssConfig = { loader: 'postcss-loader' };
const userHasPostcssConfig = fs.existsSync(userPostcssConfigPath);

if (userHasPostcssConfig) {
logger.info(`Using postcss config: ${userPostcssConfigPath}`);
// eslint-disable-next-line global-require,import/no-dynamic-require
const userPostcssConfig = require(userPostcssConfigPath);
postcssConfig.options =
typeof userPostcssConfig === 'function' ? userPostcssConfig() : userPostcssConfig;
} else {
postcssConfig.options = kytPostcssConfig;
}

module.exports = postcssConfig;
1 change: 1 addition & 0 deletions packages/kyt-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"babel-preset-kyt-core": "2.0.1"
},
"scripts": {
"watch": "yarn prepare --watch",
"prepare": "rimraf lib && babel src -d lib --ignore \"**/__tests__/**\""
},
"gitHead": "a120343756f132868e6af0cfee3579bfc3dafaa8"
Expand Down
7 changes: 6 additions & 1 deletion packages/kyt-runtime/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ export const getBundles = ({ entry = 'main', modules, assets = null, loadableBun
const runtimeBundle = assets[`runtime~${entry}.js`];
const entryBundle = assets[`${entry}.js`];
const vendorBundle = assets['vendor.js'];
const cssBundle = assets[`${entry}.css`];

const bundleManifest = {
runtimeBundle,
entryBundle,
vendorBundle,
scripts: [],
cssBundle,
};

if (!modules || modules.length === 0) {
Expand All @@ -40,11 +42,14 @@ export const getBundles = ({ entry = 'main', modules, assets = null, loadableBun

let hashes = [];
loadableBundles.entries.forEach(key => {
hashes = hashes.concat([assets[`${key}.js`]]).filter(Boolean);
hashes = hashes.concat([assets[`${key}.js`], assets[`${key}.css`]]).filter(Boolean);
});

const bundles = getLoadableBundles(loadableBundles.bundles, modules);

const cssBundles = bundles.filter(b => b.file.endsWith('.css') && !hashes.includes(b.publicPath));
bundleManifest.styles = [...new Set(cssBundles.map(b => b.publicPath))];

const jsBundles = bundles.filter(
b =>
b?.file?.endsWith('.js') &&
Expand Down
7 changes: 4 additions & 3 deletions packages/kyt-starter-universal/starter-src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
},
"homepage": "/~https://github.com/nytimes/kyt/packages/kyt-starter-universal#readme",
"scripts": {
"dev": "kyt dev",
"build": "kyt build",
"start": "node build/server/main.js",
"dev": "NODE_OPTIONS=--openssl-legacy-provider kyt dev",
"build": "NODE_OPTIONS=--openssl-legacy-provider kyt build",
"start": "NODE_OPTIONS=--openssl-legacy-provider node build/server/main.js",
"lint": "eslint .",
"lint-fix": "eslint . --fix",
"test": "jest",
Expand Down Expand Up @@ -56,6 +56,7 @@
"eslint-plugin-prettier": "3.4.1",
"eslint-plugin-react": "7.26.0",
"eslint-plugin-react-hooks": "4.2.0",
"identity-obj-proxy": "3.0.0",
"jest": "27.2.1",
"jest-preset-kyt-rtl": "1.1.2",
"jest-preset-kyt-styled": "1.4.12",
Expand Down
Loading

0 comments on commit 1db1da1

Please sign in to comment.