Closed kossnocorp closed 3 years ago
I like it 👍
@michael-ciniawsky I've tried to came up with a code example that is easy to comprehend.
I'm building a foundation (framework) for several projects that have a similar stack, same UI library but differ in paths and other details. I'm extracting common configuration logic such as webpack, Babel, PostCSS into a module. The module reads configuration from the file system and derives the rest data required for the build system (where to build, where's sources, syncs webpack, etc.). webpack supports config promises, so halfway through I realized that PostCSS don't.
@michael-ciniawsky I've fixed your comments.
I need more info about this logic you intend to introduce with your framework, e.g postcss-load-config
starts looking up the config relative to the file (dirname
) and uses the first occurrence found (bottom-up), so maybe dropping a postcss.config.js
in the root of your project (framework) would already by sufficient in this case
App
|– src
||– app.css (2)
|
|– node_modules
||– framework
|||– file.css (1)
|||– postcss.config.js (1)
|
|– postcss.config.js (2)
|– webpack.config.js
My postcss.config.js
is:
module.exports = require('./GECK/postcss/config')
./GECK/postcss/config
reads app config and returns promise to PostCSS configuration:
const path = require('path')
const ResolverFactory = require('enhanced-resolve/lib/ResolverFactory')
const NodeJsInputFileSystem = require('enhanced-resolve/lib/NodeJsInputFileSystem')
const CachedInputFileSystem = require('enhanced-resolve/lib/CachedInputFileSystem')
require('ts-node').register()
const { getBundleConfig } = require('../bundleConfig')
const rootPath = process.cwd()
const cachedDuration = 60000
const fileSystem = new CachedInputFileSystem(
new NodeJsInputFileSystem(),
cachedDuration
)
const configPromise = getBundleConfig().then(bundleConfig => {
const resolver = ResolverFactory.createResolver({
alias: {
'#app': path.resolve(rootPath, `src/${bundleConfig.name}`),
'#GECK': path.resolve(rootPath, 'GECK')
},
extensions: ['.css'],
modules: ['node_modules'],
useSyncFileSystemCalls: true,
fileSystem
})
return {
plugins: [
require('postcss-import')({
resolve: (id, basedir) => resolver.resolveSync({}, basedir, id)
}),
require('postcss-preset-env')({ stage: 0 }),
require('cssnano')()
]
}
})
module.exports = configPromise
Placement of postcss.config.js
couldn't help in this case.
Could you post a intended file tree/structure (especially for the @import
's)?
{Promise}
for webbpack.config.js
(Is it a requirement)? Everyting alse seems to be syncpostcss-import
, use the css-loader
instead to avoid duplicatesctx
has a file
prop (the current file being processed) which can be used to resolve dependencies in a different way ([modified] and passed as an potential plugin option) for/per file. Why isn't that sufficient?Which concrete problems during development lead you to solve it in that particular way? Support for webpack
aliases?
There is also (since webpack >= v4.0.0
)
webpack.config.js
{
module: {
rules: [
{
test: /\.css$/,
use: [..., 'css-loader', 'postcss-loader', ...],
resolve: { // <= Scoped resolver options (enhanced-resolve)
...options
}
}
]
}
}
This PR adds an ability to return a Promise from the config:
It enables advanced configuration, for example, syncing with webpack config:
I also had to update Jest because it was throwing
SecurityError: localStorage is not available for opaque origins
. See for more details: https://github.com/facebook/jest/issues/6766.