Skip to content

Commit

Permalink
STRWEB-69: Add support for transpilation (#73)
Browse files Browse the repository at this point in the history
* Add support for transpilation

* Cleanup

* Cleanup

* Continue on transpilation

* Cleanup

* Cleanup

* Cleanup

* More work on transpilation

* Cleanup

* Cleanup

* Cleanup

* Cleanup

* Cleanup

* Cleanup

* Cleanup

* More work on transpilation

* Cleanup

* Cleanup

* Cleanup

* Handle already transpiled CSS files

* Cleanup

* Cleanup

* Fix tests

* Add woff2 support

* Remove empty scripts

* skip stripes-ui from transpilation

* Add disableDeprecationNotice to postcss

* Improve path resolution

* Update css entry

* use path.sep

* Cleanup

* Adjust css dist path regex

* More cleanup for Windows

* Fix tests

* Cleanup css based on feedback

* Adjust tsconfig

* Cleanup

* Remove only to run all tests

* Adjust dependencies

* Add ts and tsx to babel-loader test in transpilation config

* Adjust shared styles
  • Loading branch information
mkuklis authored Mar 21, 2023
1 parent 94a13cf commit c59da7d
Show file tree
Hide file tree
Showing 19 changed files with 557 additions and 237 deletions.
32 changes: 32 additions & 0 deletions consts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// The list of the default externals
// https://webpack.js.org/configuration/externals/
const defaultExternals = [
'@folio/stripes',
'@folio/stripes-components',
'@folio/stripes-connect',
'@folio/stripes-core',
'@folio/stripes-util',
'@folio/stripes-form',
'@folio/stripes-final-form',
'@folio/stripes-logger',
'@folio/stripes-smart-components',
'final-form',
'final-form-arrays',
'moment',
'moment-timezone',
'react',
'react-dom',
'react-final-form',
'react-final-form-arrays',
'react-final-form-listeners',
'react-intl',
'react-query',
'react-redux',
'react-router',
'redux',
'stripes-config',
];

module.exports = {
defaultExternals,
};
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,21 @@
"regenerator-runtime": "^0.13.3",
"semver": "^7.1.3",
"serialize-javascript": "^5.0.0",
"source-map-loader": "^4.0.0",
"speed-measure-webpack-plugin": "^1.5.0",
"stream-browserify": "^3.0.0",
"style-loader": "^3.3.0",
"svgo": "^1.2.2",
"svgo-loader": "^2.2.1",
"tapable": "^1.0.0",
"terser-webpack-plugin": "^5.3.5",
"ts-loader": "^9.4.1",
"typescript": "^4.2.4",
"url-loader": "^4.1.1",
"util-ex": "^0.3.15",
"webpack-dev-middleware": "^5.2.1",
"webpack-hot-middleware": "^2.25.1",
"webpack-remove-empty-scripts": "^1.0.1",
"webpack-virtual-modules": "^0.4.3"
},
"devDependencies": {
Expand Down
39 changes: 39 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const path = require('path');
const postCssImport = require('postcss-import');
const autoprefixer = require('autoprefixer');
const postCssCustomProperties = require('postcss-custom-properties');
const postCssCalc = require('postcss-calc');
const postCssNesting = require('postcss-nesting');
const postCssCustomMedia = require('postcss-custom-media');
const postCssMediaMinMax = require('postcss-media-minmax');
const postCssColorFunction = require('postcss-color-function');

const { generateStripesAlias, tryResolve } = require('./webpack/module-paths');

const locateCssVariables = () => {
const variables = 'lib/variables.css';
const localPath = path.join(path.resolve(), variables);

// check if variables are present locally (in cases when stripes-components is
// being built directly) if not look for them via stripes aliases
return tryResolve(localPath) ?
localPath :
path.join(generateStripesAlias('@folio/stripes-components'), variables);
};

module.exports = {
plugins: [
postCssImport(),
autoprefixer(),
postCssCustomProperties({
preserve: false,
importFrom: [locateCssVariables()],
disableDeprecationNotice: true
}),
postCssCalc(),
postCssNesting(),
postCssCustomMedia(),
postCssMediaMinMax(),
postCssColorFunction(),
],
};
14 changes: 7 additions & 7 deletions test/webpack/babel-loader-rule.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,32 @@ const babelLoaderRule = require('../../webpack/babel-loader-rule');
describe('The babel-loader-rule', function () {
describe('test condition function', function () {
beforeEach(function () {
this.sut = babelLoaderRule({ modules: {} }).test;
this.sut = babelLoaderRule(['@folio/inventory']);
});

it('selects files for @folio scoped node_modules', function () {
const fileName = '/projects/folio/folio-testing-platform/node_modules/@folio/inventory/index.js';
const result = this.sut(fileName);
const fileName = '/projects/folio/folio-testing-platform/node_modules/stripes-config';
const result = this.sut.include(fileName);
expect(result).to.equal(true);
});

it('does not select node_modules files outside of @folio scope', function () {
const fileName = '/projects/folio/folio-testing-platform/node_modules/lodash/lodash.js';
const result = this.sut(fileName);
const result = this.sut.include(fileName);
expect(result).to.equal(false);
});

it('only selects .js file extensions', function () {
const fileName = '/project/folio/folio-testing-platform/node_modules/@folio/search/package.json';
const result = this.sut(fileName);
expect(result).to.equal(false);
const result = fileName.match(this.sut.test);
expect(result).to.equal(null);
});

it('selects files outside of both @folio scope and node_modules', function () {
// This test case would hold true for yarn-linked modules, @folio scoped or otherwise
// Therefore this implies that we are not yarn-linking any non-@folio scoped modules
const fileName = '/projects/folio/stripes-core/src/configureLogger.js';
const result = this.sut(fileName);
const result = this.sut.include(fileName);
expect(result).to.equal(true);
});
});
Expand Down
83 changes: 80 additions & 3 deletions webpack.config.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ const fs = require('fs');
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');

const { generateStripesAlias } = require('./webpack/module-paths');
const babelLoaderRule = require('./webpack/babel-loader-rule');
const typescriptLoaderRule = require('./webpack/typescript-loader-rule');
const { isProduction } = require('./webpack/utils');
const { getTranspiledCssPaths } = require('./webpack/module-paths');

// React doesn't like being included multiple times as can happen when using
// yarn link. Here we find a more specific path to it by first looking in
Expand Down Expand Up @@ -36,9 +40,9 @@ const specificReact = generateStripesAlias('react');
// Since we are now on the webpack 5 we can make use of dependOn (https://webpack.js.org/configuration/entry-context/#dependencies)
// in order to create a dependency between stripes config and other chunks:

module.exports = {
const baseConfig = {
entry: {
css: '@folio/stripes-components/lib/global.css',
css: ['@folio/stripes-components/lib/global.css'],
stripesConfig: {
import: 'stripes-config.js'
},
Expand All @@ -60,6 +64,7 @@ module.exports = {
template: fs.existsSync('index.html') ? 'index.html' : `${__dirname}/index.html`,
}),
new webpack.EnvironmentPlugin(['NODE_ENV']),
new RemoveEmptyScriptsPlugin(),
],
module: {
rules: [
Expand Down Expand Up @@ -97,6 +102,78 @@ module.exports = {
loader: 'csv-loader',
}],
},
{
test: /\.js.map$/,
enforce: 'pre',
use: ['source-map-loader'],
},
{
test: /\.svg$/,
use: [{
loader: 'url-loader',
options: {
esModule: false,
},
}]
},
],
},
};


const buildConfig = (modulePaths) => {
const transpiledCssPaths = getTranspiledCssPaths(modulePaths);
const cssDistPathRegex = /dist[\/\\]style\.css/;

// already transpiled css files
if (transpiledCssPaths.length) {
transpiledCssPaths.forEach(cssPath => {
baseConfig.entry.css.push(cssPath);
});

baseConfig.module.rules.push({
test: /\.css$/,
include: [cssDistPathRegex],
use: [
{ loader: isProduction ? MiniCssExtractPlugin.loader : 'style-loader' },
{
loader: 'css-loader',
options: {
modules: false
},
},
],
});
}

// css files not transpiled yet
baseConfig.module.rules.push({
test: /\.css$/,
exclude: [cssDistPathRegex],
use: [
{ loader: isProduction ? MiniCssExtractPlugin.loader : 'style-loader' },
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[local]---[hash:base64:5]',
},
importLoaders: 1,
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
config: path.resolve(__dirname, 'postcss.config.js'),
},
sourceMap: true,
},
},
]
});

return baseConfig;
}

module.exports = buildConfig;
97 changes: 14 additions & 83 deletions webpack.config.cli.dev.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,27 @@
// Top level Webpack configuration for running a development environment
// from the command line via devServer.js

const path = require('path');
const webpack = require('webpack');
const postCssImport = require('postcss-import');
const autoprefixer = require('autoprefixer');
const postCssCustomProperties = require('postcss-custom-properties');
const postCssCalc = require('postcss-calc');
const postCssNesting = require('postcss-nesting');
const postCssCustomMedia = require('postcss-custom-media');
const postCssMediaMinMax = require('postcss-media-minmax');
const postCssColorFunction = require('postcss-color-function');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const babelLoaderRule = require('./webpack/babel-loader-rule');

const { generateStripesAlias, tryResolve } = require('./webpack/module-paths');
const { getModulesPaths, getStripesModulesPaths } = require('./webpack/module-paths');
const { tryResolve } = require('./webpack/module-paths');
const babelLoaderRule = require('./webpack/babel-loader-rule');
const utils = require('./webpack/utils');

const base = require('./webpack.config.base');
const buildBaseConfig = require('./webpack.config.base');
const cli = require('./webpack.config.cli');


const buildConfig = (stripesConfig) => {

const locateCssVariables = () => {
const variables = 'lib/variables.css';
const localPath = path.join(path.resolve(), variables);

// check if variables are present locally (in cases when stripes-components is
// being built directly) if not look for them via stripes aliases
return tryResolve(localPath) ?
localPath :
path.join(generateStripesAlias('@folio/stripes-components'), variables);
};
const useBrowserMocha = () => {
return tryResolve('mocha/mocha-es2018.js') ? 'mocha/mocha-es2018.js' : 'mocha';
};

const useBrowserMocha = () => {
return tryResolve('mocha/mocha-es2018.js') ? 'mocha/mocha-es2018.js' : 'mocha';
};
const buildConfig = (stripesConfig) => {
const modulePaths = getModulesPaths(stripesConfig.modules);
const stripesModulePaths = getStripesModulesPaths();
const allModulePaths = [...stripesModulePaths, ...modulePaths];

const base = buildBaseConfig(allModulePaths);
const devConfig = Object.assign({}, base, cli, {
devtool: 'inline-source-map',
mode: 'development',
Expand All @@ -56,7 +40,7 @@ const buildConfig = (stripesConfig) => {
devConfig.output.filename = 'bundle.js';
devConfig.entry = [
'webpack-hot-middleware/client',
'@folio/stripes-components/lib/global.css',
...devConfig.entry.css,
'@folio/stripes-ui',
];

Expand All @@ -78,48 +62,7 @@ const buildConfig = (stripesConfig) => {
devConfig.resolve.alias.process = 'process/browser.js';
devConfig.resolve.alias['mocha'] = useBrowserMocha();

devConfig.module.rules.push(babelLoaderRule(stripesConfig));

devConfig.module.rules.push({
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[local]---[hash:base64:5]',
},
sourceMap: true,
importLoaders: 1,
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
postCssImport(),
autoprefixer(),
postCssCustomProperties({
preserve: false,
importFrom: [locateCssVariables()],
disableDeprecationNotice: true
}),
postCssCalc(),
postCssNesting(),
postCssCustomMedia(),
postCssMediaMinMax(),
postCssColorFunction(),
],
},
sourceMap: true,
},
},
],
});
devConfig.module.rules.push(babelLoaderRule(allModulePaths));

// add 'Buffer' global required for tests/reporting tools.
devConfig.plugins.push(
Expand All @@ -135,18 +78,6 @@ const buildConfig = (stripesConfig) => {
"util": require.resolve('util-ex'),
};

devConfig.module.rules.push(
{
test: /\.svg$/,
use: [{
loader: 'file-loader?name=img/[path][name].[contenthash].[ext]',
options: {
esModule: false,
},
}]
},
);

return devConfig;
}

Expand Down
1 change: 1 addition & 0 deletions webpack.config.cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ module.exports = {
filename: 'bundle.[name][contenthash].js',
chunkFilename: 'chunk.[name][chunkhash].js',
publicPath: '/',
clean: true
},
};
Loading

0 comments on commit c59da7d

Please sign in to comment.