Merge branch 'master' into next
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
# We don't declare them here — take a look at our docs.
|
# We don't declare them here — take a look at our docs.
|
||||||
# https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md
|
# https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md
|
||||||
|
|
||||||
FROM nginx:1.23.4-alpine
|
FROM nginx:1.24.0-alpine
|
||||||
|
|
||||||
RUN apk update && apk add --no-cache "nodejs>=18.14.1-r0 "
|
RUN apk update && apk add --no-cache "nodejs>=18.14.1-r0 "
|
||||||
|
|
||||||
|
|||||||
@@ -177,6 +177,49 @@ Redirect url given as parameter to the oauth2 provider. Default the url refers t
|
|||||||
⚠️ This prop is currently only applied once, on mount. Changes to this prop's value will not be propagated to the underlying Swagger UI instance. A future version of this module will remove this limitation, and the change will not be considered a breaking change.
|
⚠️ This prop is currently only applied once, on mount. Changes to this prop's value will not be propagated to the underlying Swagger UI instance. A future version of this module will remove this limitation, and the change will not be considered a breaking change.
|
||||||
|
|
||||||
|
|
||||||
|
## Next.js
|
||||||
|
|
||||||
|
When using [Next.js](https://nextjs.org/), following options are available for seamless integration of `swagger-ui-react`:
|
||||||
|
|
||||||
|
#### 1. Make sure to enable transpilation for following dependencies `next.config.js`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const nextConfig = {
|
||||||
|
transpilePackages: [
|
||||||
|
'swagger-ui-react',
|
||||||
|
'swagger-client',
|
||||||
|
'react-syntax-highlighter',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```js
|
||||||
|
const withTM = require('next-transpile-modules')([
|
||||||
|
'swagger-ui-react',
|
||||||
|
'swagger-client'
|
||||||
|
'react-syntax-highlighter',
|
||||||
|
]);
|
||||||
|
|
||||||
|
const nextConfig = {
|
||||||
|
reactStrictMode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = withTM(nextConfig);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Use dynamic import
|
||||||
|
|
||||||
|
```js
|
||||||
|
import dynamic from "next/dynamic";
|
||||||
|
|
||||||
|
const SwaggerUI = dynamic(import('swagger-ui-react'), {ssr: false})
|
||||||
|
|
||||||
|
const Test = () => <SwaggerUI spec={data}/>
|
||||||
|
export default Test
|
||||||
|
```
|
||||||
|
|
||||||
|
More information about Next.js integration can be found in [#7970](https://github.com/swagger-api/swagger-ui/issues/7970) and (#8245)[https://github.com/swagger-api/swagger-ui/issues/8245].
|
||||||
|
|
||||||
|
|
||||||
## Limitations
|
## Limitations
|
||||||
|
|
||||||
|
|||||||
4264
package-lock.json
generated
4264
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -93,7 +93,7 @@
|
|||||||
"reselect": "^4.1.8",
|
"reselect": "^4.1.8",
|
||||||
"serialize-error": "^8.1.0",
|
"serialize-error": "^8.1.0",
|
||||||
"sha.js": "^2.4.11",
|
"sha.js": "^2.4.11",
|
||||||
"swagger-client": "^3.19.7",
|
"swagger-client": "^3.19.8",
|
||||||
"url-parse": "^1.5.10",
|
"url-parse": "^1.5.10",
|
||||||
"xml": "=1.0.1",
|
"xml": "=1.0.1",
|
||||||
"xml-but-prettier": "^1.0.1",
|
"xml-but-prettier": "^1.0.1",
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
"@babel/plugin-transform-modules-commonjs": "=7.21.5",
|
"@babel/plugin-transform-modules-commonjs": "=7.21.5",
|
||||||
"@babel/plugin-transform-runtime": "=7.21.0",
|
"@babel/plugin-transform-runtime": "=7.21.0",
|
||||||
"@babel/preset-env": "=7.21.5",
|
"@babel/preset-env": "=7.21.5",
|
||||||
"@babel/preset-react": "=7.14.5",
|
"@babel/preset-react": "=7.18.6",
|
||||||
"@babel/register": "=7.21.0",
|
"@babel/register": "=7.21.0",
|
||||||
"@commitlint/cli": "^17.6.1",
|
"@commitlint/cli": "^17.6.1",
|
||||||
"@commitlint/config-conventional": "^17.6.3",
|
"@commitlint/config-conventional": "^17.6.3",
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cross-env": "=7.0.3",
|
"cross-env": "=7.0.3",
|
||||||
"css-loader": "=6.7.3",
|
"css-loader": "=6.7.4",
|
||||||
"cssnano": "=6.0.1",
|
"cssnano": "=6.0.1",
|
||||||
"cypress": "=9.5.1",
|
"cypress": "=9.5.1",
|
||||||
"dedent": "^0.7.0",
|
"dedent": "^0.7.0",
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
"license-checker": "^25.0.0",
|
"license-checker": "^25.0.0",
|
||||||
"lint-staged": "^13.2.2",
|
"lint-staged": "^13.2.2",
|
||||||
"local-web-server": "^5.3.0",
|
"local-web-server": "^5.3.0",
|
||||||
"mini-css-extract-plugin": "^2.7.5",
|
"mini-css-extract-plugin": "^2.7.6",
|
||||||
"mocha": "=8.4.0",
|
"mocha": "=8.4.0",
|
||||||
"npm-audit-ci-wrapper": "^3.0.2",
|
"npm-audit-ci-wrapper": "^3.0.2",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
@@ -172,7 +172,7 @@
|
|||||||
"release-it": "=15.4.2",
|
"release-it": "=15.4.2",
|
||||||
"rimraf": "^5.0.0",
|
"rimraf": "^5.0.0",
|
||||||
"sass": "^1.62.1",
|
"sass": "^1.62.1",
|
||||||
"sass-loader": "^12.6.0",
|
"sass-loader": "^13.3.0",
|
||||||
"sinon": "=15.0.4",
|
"sinon": "=15.0.4",
|
||||||
"source-map-support": "^0.5.21",
|
"source-map-support": "^0.5.21",
|
||||||
"start-server-and-test": "^2.0.0",
|
"start-server-and-test": "^2.0.0",
|
||||||
|
|||||||
@@ -273,11 +273,12 @@ export function restoreAuthorization(payload) {
|
|||||||
|
|
||||||
export const persistAuthorizationIfNeeded = () => ( { authSelectors, getConfigs } ) => {
|
export const persistAuthorizationIfNeeded = () => ( { authSelectors, getConfigs } ) => {
|
||||||
const configs = getConfigs()
|
const configs = getConfigs()
|
||||||
if (configs.persistAuthorization)
|
|
||||||
{
|
if (!configs.persistAuthorization) return
|
||||||
const authorized = authSelectors.authorized()
|
|
||||||
localStorage.setItem("authorized", JSON.stringify(authorized.toJS()))
|
// persist authorization to local storage
|
||||||
}
|
const authorized = authSelectors.authorized().toJS()
|
||||||
|
localStorage.setItem("authorized", JSON.stringify(authorized))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const authPopup = (url, swaggerUIRedirectOauth2) => ( ) => {
|
export const authPopup = (url, swaggerUIRedirectOauth2) => ( ) => {
|
||||||
|
|||||||
19
src/core/plugins/auth/configs-extensions/wrap-actions.js
Normal file
19
src/core/plugins/auth/configs-extensions/wrap-actions.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
export const loaded = (oriAction, system) => (payload) => {
|
||||||
|
const { getConfigs, authActions } = system
|
||||||
|
const configs = getConfigs()
|
||||||
|
|
||||||
|
oriAction(payload)
|
||||||
|
|
||||||
|
// check if we should restore authorization data from localStorage
|
||||||
|
if (configs.persistAuthorization) {
|
||||||
|
const authorized = localStorage.getItem("authorized")
|
||||||
|
if (authorized) {
|
||||||
|
authActions.restoreAuthorization({
|
||||||
|
authorized: JSON.parse(authorized),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import reducers from "./reducers"
|
import reducers from "./reducers"
|
||||||
import * as actions from "./actions"
|
import * as actions from "./actions"
|
||||||
import * as selectors from "./selectors"
|
import * as selectors from "./selectors"
|
||||||
import * as specWrapActionReplacements from "./spec-wrap-actions"
|
import { execute as wrappedExecuteAction } from "./spec-extensions/wrap-actions"
|
||||||
|
import { loaded as wrappedLoadedAction } from "./configs-extensions/wrap-actions"
|
||||||
|
import { authorize as wrappedAuthorizeAction, logout as wrappedLogoutAction } from "./wrap-actions"
|
||||||
|
|
||||||
export default function() {
|
export default function() {
|
||||||
return {
|
return {
|
||||||
@@ -15,11 +17,22 @@ export default function() {
|
|||||||
auth: {
|
auth: {
|
||||||
reducers,
|
reducers,
|
||||||
actions,
|
actions,
|
||||||
selectors
|
selectors,
|
||||||
|
wrapActions: {
|
||||||
|
authorize: wrappedAuthorizeAction,
|
||||||
|
logout: wrappedLogoutAction,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
configs: {
|
||||||
|
wrapActions: {
|
||||||
|
loaded: wrappedLoadedAction,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
spec: {
|
spec: {
|
||||||
wrapActions: specWrapActionReplacements
|
wrapActions: {
|
||||||
}
|
execute: wrappedExecuteAction,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
64
src/core/plugins/auth/wrap-actions.js
Normal file
64
src/core/plugins/auth/wrap-actions.js
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `authorize` and `logout` wrapped actions provide capacity
|
||||||
|
* to persist cookie based apiKey in document.cookie.
|
||||||
|
*
|
||||||
|
* `persistAuthorization` SwaggerUI options needs to set to `true`
|
||||||
|
* for document.cookie persistence to work.
|
||||||
|
*/
|
||||||
|
export const authorize = (oriAction, system) => (payload) => {
|
||||||
|
oriAction(payload)
|
||||||
|
|
||||||
|
const configs = system.getConfigs()
|
||||||
|
|
||||||
|
if (!configs.persistAuthorization) return
|
||||||
|
|
||||||
|
// create cookie
|
||||||
|
try {
|
||||||
|
const [{ schema, value }] = Object.values(payload)
|
||||||
|
const isApiKeyAuth = schema.get("type") === "apiKey"
|
||||||
|
const isInCookie = schema.get("in") === "cookie"
|
||||||
|
const isApiKeyInCookie = isApiKeyAuth && isInCookie
|
||||||
|
|
||||||
|
if (isApiKeyInCookie) {
|
||||||
|
document.cookie = `${schema.get("name")}=${value}; SameSite=None; Secure`
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
"Error persisting cookie based apiKey in document.cookie.",
|
||||||
|
error
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const logout = (oriAction, system) => (payload) => {
|
||||||
|
const configs = system.getConfigs()
|
||||||
|
const authorized = system.authSelectors.authorized()
|
||||||
|
|
||||||
|
// deleting cookie
|
||||||
|
try {
|
||||||
|
if (configs.persistAuthorization && Array.isArray(payload)) {
|
||||||
|
payload.forEach((authorizedName) => {
|
||||||
|
const auth = authorized.get(authorizedName, {})
|
||||||
|
const isApiKeyAuth = auth.getIn(["schema", "type"]) === "apiKey"
|
||||||
|
const isInCookie = auth.getIn(["schema", "in"]) === "cookie"
|
||||||
|
const isApiKeyInCookie = isApiKeyAuth && isInCookie
|
||||||
|
|
||||||
|
if (isApiKeyInCookie) {
|
||||||
|
const cookieName = auth.getIn(["schema", "name"])
|
||||||
|
document.cookie = `${cookieName}=; Max-Age=-99999999`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
"Error deleting cookie based apiKey from document.cookie.",
|
||||||
|
error
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
oriAction(payload)
|
||||||
|
}
|
||||||
@@ -21,17 +21,6 @@ export function toggle(configName) {
|
|||||||
|
|
||||||
|
|
||||||
// Hook
|
// Hook
|
||||||
export const loaded = () => ({getConfigs, authActions}) => {
|
export const loaded = () => () => {
|
||||||
// check if we should restore authorization data from localStorage
|
// noop
|
||||||
const configs = getConfigs()
|
|
||||||
if (configs.persistAuthorization)
|
|
||||||
{
|
|
||||||
const authorized = localStorage.getItem("authorized")
|
|
||||||
if(authorized)
|
|
||||||
{
|
|
||||||
authActions.restoreAuthorization({
|
|
||||||
authorized: JSON.parse(authorized)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { loaded } from "corePlugins/auth/configs-extensions/wrap-actions"
|
||||||
|
|
||||||
|
describe("loaded hook", () => {
|
||||||
|
describe("authorization data restoration", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
localStorage.clear()
|
||||||
|
})
|
||||||
|
it("retrieve `authorized` value from `localStorage`", () => {
|
||||||
|
const system = {
|
||||||
|
getConfigs: () => ({
|
||||||
|
persistAuthorization: true
|
||||||
|
}),
|
||||||
|
authActions: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jest.spyOn(Object.getPrototypeOf(window.localStorage), "getItem")
|
||||||
|
|
||||||
|
loaded(jest.fn(), system)()
|
||||||
|
expect(localStorage.getItem).toHaveBeenCalled()
|
||||||
|
expect(localStorage.getItem).toHaveBeenCalledWith("authorized")
|
||||||
|
})
|
||||||
|
it("restore authorization data when a value exists", () => {
|
||||||
|
const system = {
|
||||||
|
getConfigs: () => ({
|
||||||
|
persistAuthorization: true
|
||||||
|
}),
|
||||||
|
authActions: {
|
||||||
|
restoreAuthorization: jest.fn(() => {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const mockData = {"api_key": {}}
|
||||||
|
localStorage.setItem("authorized", JSON.stringify(mockData))
|
||||||
|
loaded(jest.fn(), system)()
|
||||||
|
expect(system.authActions.restoreAuthorization).toHaveBeenCalled()
|
||||||
|
expect(system.authActions.restoreAuthorization).toHaveBeenCalledWith({
|
||||||
|
authorized: mockData
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
|
import { execute } from "corePlugins/auth/spec-extensions/wrap-actions"
|
||||||
import { execute } from "corePlugins/auth/spec-wrap-actions"
|
|
||||||
|
|
||||||
describe("spec plugin - actions", function(){
|
describe("spec plugin - actions", function(){
|
||||||
|
|
||||||
119
test/unit/core/plugins/auth/wrap-actions.js
Normal file
119
test/unit/core/plugins/auth/wrap-actions.js
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
import { fromJS } from "immutable"
|
||||||
|
import { authorize, logout } from "corePlugins/auth/wrap-actions"
|
||||||
|
|
||||||
|
describe("Cookie based apiKey persistence in document.cookie", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
let cookieJar = ""
|
||||||
|
jest.spyOn(document, "cookie", "set").mockImplementation((cookie) => {
|
||||||
|
cookieJar += cookie
|
||||||
|
})
|
||||||
|
jest.spyOn(document, "cookie", "get").mockImplementation(() => cookieJar)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.restoreAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("given persistAuthorization=true", () => {
|
||||||
|
it("should persist cookie in document.cookie", () => {
|
||||||
|
const system = {
|
||||||
|
getConfigs: () => ({
|
||||||
|
persistAuthorization: true,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
const payload = {
|
||||||
|
api_key: {
|
||||||
|
schema: fromJS({
|
||||||
|
type: "apiKey",
|
||||||
|
name: "apiKeyCookie",
|
||||||
|
in: "cookie",
|
||||||
|
}),
|
||||||
|
value: "test",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
authorize(jest.fn(), system)(payload)
|
||||||
|
|
||||||
|
expect(document.cookie).toEqual(
|
||||||
|
"apiKeyCookie=test; SameSite=None; Secure"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should delete cookie from document.cookie", () => {
|
||||||
|
const payload = fromJS({
|
||||||
|
api_key: {
|
||||||
|
schema: {
|
||||||
|
type: "apiKey",
|
||||||
|
name: "apiKeyCookie",
|
||||||
|
in: "cookie",
|
||||||
|
},
|
||||||
|
value: "test",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const system = {
|
||||||
|
getConfigs: () => ({
|
||||||
|
persistAuthorization: true,
|
||||||
|
}),
|
||||||
|
authSelectors: {
|
||||||
|
authorized: () => payload,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
logout(jest.fn(), system)(["api_key"])
|
||||||
|
|
||||||
|
expect(document.cookie).toEqual("apiKeyCookie=; Max-Age=-99999999")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("given persistAuthorization=false", () => {
|
||||||
|
it("shouldn't persist cookie in document.cookie", () => {
|
||||||
|
const system = {
|
||||||
|
getConfigs: () => ({
|
||||||
|
persistAuthorization: false,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
const payload = {
|
||||||
|
api_key: {
|
||||||
|
schema: fromJS({
|
||||||
|
type: "apiKey",
|
||||||
|
name: "apiKeyCookie",
|
||||||
|
in: "cookie",
|
||||||
|
}),
|
||||||
|
value: "test",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
authorize(jest.fn(), system)(payload)
|
||||||
|
|
||||||
|
expect(document.cookie).toEqual("")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should delete cookie from document.cookie", () => {
|
||||||
|
const payload = fromJS({
|
||||||
|
api_key: {
|
||||||
|
schema: {
|
||||||
|
type: "apiKey",
|
||||||
|
name: "apiKeyCookie",
|
||||||
|
in: "cookie",
|
||||||
|
},
|
||||||
|
value: "test",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const system = {
|
||||||
|
getConfigs: () => ({
|
||||||
|
persistAuthorization: false,
|
||||||
|
}),
|
||||||
|
authSelectors: {
|
||||||
|
authorized: () => payload,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
logout(jest.fn(), system)(["api_key"])
|
||||||
|
|
||||||
|
expect(document.cookie).toEqual("")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { downloadConfig } from "corePlugins/configs/spec-actions"
|
import { downloadConfig } from "corePlugins/configs/spec-actions"
|
||||||
import { loaded } from "corePlugins/configs/actions"
|
|
||||||
|
|
||||||
describe("configs plugin - actions", () => {
|
describe("configs plugin - actions", () => {
|
||||||
|
|
||||||
@@ -23,43 +22,4 @@ describe("configs plugin - actions", () => {
|
|||||||
expect(fetchSpy).toHaveBeenCalledWith(req)
|
expect(fetchSpy).toHaveBeenCalledWith(req)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("loaded hook", () => {
|
|
||||||
describe("authorization data restoration", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
localStorage.clear()
|
|
||||||
})
|
|
||||||
it("retrieve `authorized` value from `localStorage`", () => {
|
|
||||||
const system = {
|
|
||||||
getConfigs: () => ({
|
|
||||||
persistAuthorization: true
|
|
||||||
}),
|
|
||||||
authActions: {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jest.spyOn(Object.getPrototypeOf(window.localStorage), "getItem")
|
|
||||||
loaded()(system)
|
|
||||||
expect(localStorage.getItem).toHaveBeenCalled()
|
|
||||||
expect(localStorage.getItem).toHaveBeenCalledWith("authorized")
|
|
||||||
})
|
|
||||||
it("restore authorization data when a value exists", () => {
|
|
||||||
const system = {
|
|
||||||
getConfigs: () => ({
|
|
||||||
persistAuthorization: true
|
|
||||||
}),
|
|
||||||
authActions: {
|
|
||||||
restoreAuthorization: jest.fn(() => {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const mockData = {"api_key": {}}
|
|
||||||
localStorage.setItem("authorized", JSON.stringify(mockData))
|
|
||||||
loaded()(system)
|
|
||||||
expect(system.authActions.restoreAuthorization).toHaveBeenCalled()
|
|
||||||
expect(system.authActions.restoreAuthorization).toHaveBeenCalledWith({
|
|
||||||
authorized: mockData
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -34,10 +34,9 @@ export default {
|
|||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
plugins: [
|
plugins: [
|
||||||
require("cssnano")(),
|
require("cssnano")(),
|
||||||
"postcss-preset-env" // applies autoprefixer
|
"postcss-preset-env", // applies autoprefixer
|
||||||
],
|
],
|
||||||
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -47,9 +46,7 @@ export default {
|
|||||||
implementation: require("sass"),
|
implementation: require("sass"),
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
sassOptions: {
|
sassOptions: {
|
||||||
// `fibers` package is not compatible with Node.js v16.0.0 or later
|
quietDeps: true,
|
||||||
fiber: false, // disable auto attempt to load `fiber`
|
|
||||||
// sourceMapContents: "true", // if sourceMap: true, sassOptions.sourceMapContents is ignored
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user