-
-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add logic to sass rule conditional on sass-loader version #508
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"main": "./wat", | ||
"version": "12.0.0" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"main": "./lib/api.js", | ||
"version": "16.56.81" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
module.exports = { | ||
roots: ["<rootDir>/test"], | ||
testPathIgnorePatterns: ["/__fixtures__/", "/__utils__/"] | ||
testPathIgnorePatterns: ["/__fixtures__/", "/__utils__/"], | ||
resolver: "<rootDir>/test/resolver" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,18 @@ | ||
/* eslint global-require: 0 */ | ||
|
||
const getStyleRule = require("../utils/getStyleRule") | ||
const { canProcess } = require("../utils/helpers") | ||
const { additional_paths: includePaths } = require("../config") | ||
const { canProcess, packageMajorVersion } = require("../utils/helpers") | ||
const { additional_paths: extraPaths } = require("../config") | ||
|
||
module.exports = canProcess("sass-loader", (resolvedPath) => | ||
getStyleRule(/\.(scss|sass)(\.erb)?$/i, [ | ||
module.exports = canProcess("sass-loader", (resolvedPath) => { | ||
const optionKey = | ||
packageMajorVersion("sass-loader") > 15 ? "loadPaths" : "includePaths" | ||
return getStyleRule(/\.(scss|sass)(\.erb)?$/i, [ | ||
{ | ||
loader: resolvedPath, | ||
options: { | ||
sassOptions: { includePaths } | ||
sassOptions: { [optionKey]: extraPaths } | ||
} | ||
} | ||
]) | ||
) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,10 +41,18 @@ const loaderMatches = (configLoader, loaderToCheck, fn) => { | |
return fn() | ||
} | ||
|
||
const packageMajorVersion = (packageName) => { | ||
// eslint-disable-next-line import/no-dynamic-require | ||
const packageJsonPath = require.resolve(`${packageName}/package.json`) | ||
// eslint-disable-next-line import/no-dynamic-require, global-require | ||
return require(packageJsonPath).version.match(/^\d+/)[0] | ||
} | ||
Comment on lines
+44
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve error handling. The function does not handle cases where the package version is not in the expected format or where the package does not have a Apply this diff to improve error handling: const packageMajorVersion = (packageName) => {
// eslint-disable-next-line import/no-dynamic-require
const packageJsonPath = require.resolve(`${packageName}/package.json`)
// eslint-disable-next-line import/no-dynamic-require, global-require
- return require(packageJsonPath).version.match(/^\d+/)[0]
+ const version = require(packageJsonPath).version
+ const match = version.match(/^\d+/)
+ if (!match) {
+ throw new Error(`Invalid version format for package ${packageName}`)
+ }
+ return match[0]
}
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Judahmeek any comment? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if there's no lock on the version in package.json (only yarn.lock)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The package.json that is checked is the one for the package in node_modules. I forget the last time I saw a package in node_modules that didn't have a package.json. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While technically not required by Node, the way the package managers and registries work it's all but guaranteed that there will be a (among other things it's in a packages best interest to have a fwiw you could do this using |
||
|
||
module.exports = { | ||
isBoolean, | ||
ensureTrailingSlash, | ||
canProcess, | ||
moduleExists, | ||
loaderMatches | ||
loaderMatches, | ||
packageMajorVersion | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const { packageMajorVersion } = require("../../package/utils/helpers") | ||
|
||
describe("packageMajorVersion", () => { | ||
test("should find that sass-loader is v16", () => { | ||
expect(packageMajorVersion("sass-loader")).toBe("16") | ||
}) | ||
|
||
test("should find that nonexistent is v12", () => { | ||
expect(packageMajorVersion("nonexistent")).toBe("12") | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const sass = require("../../../package/rules/sass") | ||
|
||
jest.mock("../../../package/utils/helpers", () => { | ||
const original = jest.requireActual("../../../package/utils/helpers") | ||
const canProcess = (rule, fn) => { | ||
return fn("This path was mocked") | ||
} | ||
const packageMajorVersion = () => "15" | ||
return { | ||
...original, | ||
canProcess, | ||
packageMajorVersion | ||
} | ||
}) | ||
|
||
jest.mock("../../../package/utils/inliningCss", () => true) | ||
|
||
describe("sass rule", () => { | ||
test("contains loadPaths as the sassOptions key if sass-loader is v15 or earlier", () => { | ||
expect(typeof sass.use[3].options.sassOptions.includePaths).toBe("object") | ||
expect(typeof sass.use[3].options.sassOptions.loadPaths).toBe("undefined") | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const sass = require("../../../package/rules/sass") | ||
|
||
jest.mock("../../../package/utils/helpers", () => { | ||
const original = jest.requireActual("../../../package/utils/helpers") | ||
const canProcess = (rule, fn) => { | ||
return fn("This path was mocked") | ||
} | ||
return { | ||
...original, | ||
canProcess | ||
} | ||
}) | ||
|
||
jest.mock("../../../package/utils/inliningCss", () => true) | ||
|
||
describe("sass rule", () => { | ||
test("contains loadPaths as the sassOptions key if sass-loader is v15 or earlier", () => { | ||
expect(typeof sass.use[3].options.sassOptions.includePaths).toBe( | ||
"undefined" | ||
) | ||
expect(typeof sass.use[3].options.sassOptions.loadPaths).toBe("object") | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const mapping = { | ||
"css-loader": "this path was mocked", | ||
"sass-loader/package.json": "../../__mocks__/sass-loader/package.json", | ||
"nonexistent/package.json": "../../__mocks__/nonexistent/package.json" | ||
} | ||
|
||
function resolver(module, options) { | ||
// If the path corresponds to a key in the mapping object, returns the fakely resolved path | ||
// otherwise it calls the Jest's default resolver | ||
return mapping[module] || options.defaultResolver(module, options) | ||
} | ||
|
||
module.exports = resolver |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we 100% sure that this is the only change for modern vs. legacy support?
CC: @tomdracz @G-Rath
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's seems to be the only relevant change: https://github.com/webpack-contrib/sass-loader/releases/tag/v16.0.0