Skip to content

Commit

Permalink
Resolve govuk-frontend at project level by default
Browse files Browse the repository at this point in the history
Node.js `require.resolve()` paths are optionally provided, for example:

1. Review app uses local `node_modules` before project level
2. Package stats uses local `node_modules` before project level

This is necessary for workspace `govuk-frontend@4` installs to be found
  • Loading branch information
colinrotherham committed Jun 6, 2023
1 parent 5343240 commit fd93e21
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 12 deletions.
23 changes: 16 additions & 7 deletions shared/lib/names.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const { dirname, join, parse } = require('path')

const { paths } = require('govuk-frontend-config')
const { minimatch } = require('minimatch')

/**
Expand Down Expand Up @@ -68,8 +69,12 @@ function componentPathToModuleName (componentPath) {
* @param {PackageOptions} [options] - Package resolution options
* @returns {string} Path to installed npm package entry
*/
function packageEntryToPath (packageEntry, { modulePath } = {}) {
const packagePath = require.resolve(packageEntry)
function packageEntryToPath (packageEntry, { modulePath, requirePaths } = {}) {
const packagePath = require.resolve(packageEntry, {
paths: requirePaths ?? [
join(paths.root, 'node_modules')
]
})

// Append optional module path
return modulePath !== undefined ? join(dirname(packagePath), modulePath) : packagePath
Expand All @@ -82,16 +87,17 @@ function packageEntryToPath (packageEntry, { modulePath } = {}) {
* @param {PackageOptions} [options] - Package resolution options
* @returns {string} Path to installed npm package field
*/
function packageFieldToPath (packageName, { modulePath, field = 'main' } = {}) {
function packageFieldToPath (packageName, { modulePath, requirePaths, field = 'main' } = {}) {
const packageEntry = `${packageName}/package.json`

// Package field as child path
const entryPath = require(packageEntryToPath(packageEntry))[field]
const entryPath = require(packageEntryToPath(packageEntry, { requirePaths }))[field]
const childPath = modulePath !== undefined ? join(dirname(entryPath), modulePath) : entryPath

// Append optional module path
return packageEntryToPath(packageEntry, {
modulePath: childPath
modulePath: childPath,
requirePaths
})
}

Expand All @@ -103,11 +109,13 @@ function packageFieldToPath (packageName, { modulePath, field = 'main' } = {}) {
*
* @param {string} packageName - Installed npm package name
* @param {string} [childPath] - Child directory path (optional, relative to package.json), for example `src/govuk/all.mjs`
* @param {PackageOptions} [options] - Package resolution options
* @returns {string} Path to installed npm package
*/
function packageNameToPath (packageName, childPath = '') {
function packageNameToPath (packageName, childPath = '', { requirePaths } = {}) {
return packageEntryToPath(`${packageName}/package.json`, {
modulePath: childPath
modulePath: childPath,
requirePaths
})
}

Expand All @@ -124,4 +132,5 @@ module.exports = {
* @typedef {object} PackageOptions
* @property {string} [field] - Package field name from package.json, for example `module`
* @property {string} [modulePath] - Module path (optional, relative to package entry), for example `all.mjs`
* @property {string[]} [requirePaths] - Node.js require 'node_modules` lookup paths
*/
32 changes: 32 additions & 0 deletions shared/lib/names.unit.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,35 @@ describe('packageNameToPath', () => {
.toBe(resolvedPath)
})
})

describe("packageNameToPath (with custom 'node_module' paths)", () => {
const packages = [
{
packageName: 'govuk-frontend',
childPath: 'src/govuk/all.mjs',
options: { requirePaths: [join(paths.root, 'node_modules')] },
resolvedPath: join(paths.package, 'src/govuk/all.mjs')
},
{
packageName: 'govuk-frontend-review',
childPath: 'src/app.mjs',
options: { requirePaths: [join(paths.root, 'node_modules')] },
resolvedPath: join(paths.app, 'src/app.mjs')
},
{
packageName: 'autoprefixer',
options: { requirePaths: [join(paths.package, 'node_modules')] },
resolvedPath: join(paths.root, 'node_modules/autoprefixer')
},
{
packageName: 'postcss',
options: { requirePaths: [join(paths.app, 'node_modules')] },
resolvedPath: join(paths.root, 'node_modules/postcss')
}
]

it.each(packages)("locates path for npm package '$packageName'", ({ packageName, childPath, options = {}, resolvedPath }) => {
expect(packageNameToPath(packageName, childPath, options))
.toBe(resolvedPath)
})
})
2 changes: 1 addition & 1 deletion shared/stats/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default defineConfig(modulePaths
* Input plugins
*/
plugins: [
resolve({ modulePaths: [paths.root] }),
resolve({ modulePaths: packageOptions.requirePaths }),

// Stats: File size
visualizer({
Expand Down
6 changes: 5 additions & 1 deletion shared/stats/src/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ const componentNamesWithJavaScript = await getComponentNames((componentName, com
*/
export const packageOptions = {
field: 'module',
modulePath: 'all.mjs'
modulePath: 'all.mjs',
requirePaths: [
join(paths.stats, 'node_modules'),
join(paths.root, 'node_modules')
]
}

/**
Expand Down
12 changes: 9 additions & 3 deletions shared/tasks/styles.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,16 @@ export async function compile (pattern, options) {
*
* @param {AssetEntry} assetEntry - Asset entry
*/
export async function compileStylesheet ([modulePath, { configPath, srcPath, destPath, filePath }]) {
export async function compileStylesheet ([modulePath, { configPath, srcPath, destPath, filePath, workspace }]) {
const moduleSrcPath = join(srcPath, modulePath)
const moduleDestPath = join(destPath, filePath ? filePath(parse(modulePath)) : modulePath)

// Default paths to resolve @imports
const requirePaths = [
join(workspace, 'node_modules'),
join(paths.root, 'node_modules')
]

let css
let map

Expand Down Expand Up @@ -81,8 +87,8 @@ export async function compileStylesheet ([modulePath, { configPath, srcPath, des

// Resolve @imports via
loadPaths: [
packageNameToPath('govuk-frontend', 'dist'),
join(paths.root, 'node_modules')
packageNameToPath('govuk-frontend', 'dist', { requirePaths }),
...requirePaths
],

// Sass custom logger
Expand Down

0 comments on commit fd93e21

Please sign in to comment.