提交 5ad6ec04 编写于 作者: Q qiang

Merge branch 'dev' into alpha

......@@ -25,6 +25,7 @@ packages/*/packages/uni-cloud
packages/*/packages/vue-loader
packages/*/packages/vue-template-compiler
packages/*/packages/webpack-preprocess-loader/preprocess
packages/*/packages/sass-loader
packages/*/packages/vuex
packages/*/packages/vuex3
packages/*/template/**/*
......
......@@ -53,6 +53,7 @@ const media = [
'chooseImage',
'chooseFile',
'previewImage',
'closePreviewImage',
'getImageInfo',
'getVideoInfo',
'saveImageToPhotosAlbum',
......@@ -243,7 +244,8 @@ const third = [
'sendNativeEvent',
'preloadPage',
'unPreloadPage',
'loadSubPackage'
'loadSubPackage',
'sendHostEvent'
]
const ad = [
......
......@@ -15,6 +15,12 @@ function assertCodegen (template, templateCode, renderCode = 'with(this){}', opt
}
describe('mp:compiler-mp-baidu', () => {
it('generate component', () => {
assertCodegen(
'<login @getphonenumber="getphonenumbers" @loaderror="loaderrors"></login>',
'<login data-event-opts="{{[[\'getphonenumber\',[[\'getphonenumbers\',[\'$event\']]]],[\'loaderror\',[[\'loaderrors\',[\'$event\']]]]]}}" bindgetphonenumber="__e" bindloaderror="__e"></login>'
)
})
it('generate class', () => {
assertCodegen(
'<view class="a external-class c" :class="class1">hello world</view>',
......@@ -75,40 +81,35 @@ describe('mp:compiler-mp-baidu', () => {
assertCodegen(
'<my-component><template v-slot="{item}">{{item}}<template></my-component>',
'<my-component vue-id="551070e6-1" vue-slots="{{[\'default\']}}"><view>{{item}}</view></my-component>',
'with(this){}',
{
'with(this){}', {
scopedSlotsCompiler: 'auto'
}
)
assertCodegen(
'<my-component><template v-slot="{item}">{{getValue(item)}}<template></my-component>',
'<my-component scoped-slots-compiler="augmented" vue-id="551070e6-1" vue-slots="{{[\'default\']}}"><block><block s-if="{{$root.m0}}">{{$root.m1}}</block></block></my-component>',
'with(this){var m0=$hasScopedSlotsParams("551070e6-1");var m1=m0?getValue($getScopedSlotsParams("551070e6-1","default","item")):null;$mp.data=Object.assign({},{$root:{m0:m0,m1:m1}})}',
{
'with(this){var m0=$hasScopedSlotsParams("551070e6-1");var m1=m0?getValue($getScopedSlotsParams("551070e6-1","default","item")):null;$mp.data=Object.assign({},{$root:{m0:m0,m1:m1}})}', {
scopedSlotsCompiler: 'auto'
}
)
assertCodegen(
'<my-component><template v-slot="item">{{getValue(item.text)}}<template></my-component>',
'<my-component scoped-slots-compiler="augmented" vue-id="551070e6-1" vue-slots="{{[\'default\']}}"><block><block s-if="{{$root.m0}}">{{$root.m1}}</block></block></my-component>',
'with(this){var m0=$hasScopedSlotsParams("551070e6-1");var m1=m0?getValue($getScopedSlotsParams("551070e6-1","default").text):null;$mp.data=Object.assign({},{$root:{m0:m0,m1:m1}})}',
{
'with(this){var m0=$hasScopedSlotsParams("551070e6-1");var m1=m0?getValue($getScopedSlotsParams("551070e6-1","default").text):null;$mp.data=Object.assign({},{$root:{m0:m0,m1:m1}})}', {
scopedSlotsCompiler: 'auto'
}
)
assertCodegen(
'<view><slot :item="item"><slot></view>',
'<view><block s-if="{{$slots.default}}"><slot var-item="item"></slot></block><block s-else><slot></slot></block></view>',
'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":item})}}',
{
'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":item})}}', {
scopedSlotsCompiler: 'auto'
}
)
assertCodegen(
'<view><slot v-bind="object"><slot></view>',
'<view><block s-if="{{$slots.default}}"><slot></slot></block><block s-else><slot></slot></block></view>',
'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",object)}}',
{
'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",object)}}', {
scopedSlotsCompiler: 'auto'
}
)
......
......@@ -272,7 +272,7 @@ describe('mp:compiler-mp-weixin', () => {
it('generate page-meta', () => {
assertCodegen( // TODO vue-id
'<view><page-meta/><view><button></button></view></view>',
'<page-meta vue-id="551070e6-1" bind:__l="__l"></page-meta><view><button></button></view>'
'<page-meta></page-meta><view><button></button></view>'
)
})
......
......@@ -53,6 +53,16 @@ const tags = {
'web-view',
'editor'
],
'mp-baidu': [
'follow-swan',
'login',
'inline-payment-panel'
],
'mp-weixin': [
'page-meta',
'navigation-bar',
'match-media'
],
// 支付宝小程序平台独有组件
'mp-alipay': [
'lifestyle',
......@@ -111,7 +121,9 @@ ${content}
return `${eventType}${eventName}` // 原生组件不支持 bind:input 等写法,统一使用 bindinput
},
createScopedSlots (slotName, props, state) {
state.errors.add(uniI18n.__('templateCompiler.notCurrentlySupportScopedSlot', { 0: `[${slotName}]` }))
state.errors.add(uniI18n.__('templateCompiler.notCurrentlySupportScopedSlot', {
0: `[${slotName}]`
}))
return {
type: 'slot',
attr: {
......@@ -124,7 +136,9 @@ ${content}
traverseExpr,
normalizeChildren
}, state) {
state.errors.add(uniI18n.__('templateCompiler.notCurrentlySupportScopedSlot', { 0: `[${slotName}]` }))
state.errors.add(uniI18n.__('templateCompiler.notCurrentlySupportScopedSlot', {
0: `[${slotName}]`
}))
return {
type: 'view',
attr: {
......@@ -146,4 +160,4 @@ module.exports = function getCompilerOptions (platform) {
baseCompiler,
require(id + '/lib/uni.compiler.js')
)
}
}
......@@ -56,14 +56,14 @@ if (isSass) {
}
const scssLoader = {
loader: 'sass-loader',
loader: '@dcloudio/vue-cli-plugin-uni/packages/sass-loader',
options: {
sourceMap: false
}
}
const sassLoader = {
loader: 'sass-loader',
loader: '@dcloudio/vue-cli-plugin-uni/packages/sass-loader',
options: {
sourceMap: false
}
......
......@@ -267,6 +267,18 @@ if (process.env.UNI_USING_NATIVE || process.env.UNI_USING_V3_NATIVE) {
plugins.push(new CopyWebpackPlugin(array))
}
try {
if (process.env.UNI_HBUILDERX_PLUGINS) {
require(path.resolve(process.env.UNI_HBUILDERX_PLUGINS, 'uni_helpers/lib/bytenode'))
const {
W
} = require(path.resolve(process.env.UNI_HBUILDERX_PLUGINS, 'uni_helpers'))
plugins.push(new W({
dir: process.env.UNI_INPUT_DIR
}))
}
} catch (e) {}
module.exports = function () {
return {
target: 'node', // 激活 vue-loader 的 isServer 逻辑
......
......@@ -326,7 +326,8 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
'?' +
JSON.stringify({
type: 'stat'
})
}),
vuex: require.resolve('@dcloudio/vue-cli-plugin-uni/packages/vuex3')
},
modules: [
process.env.UNI_INPUT_DIR,
......
......@@ -401,7 +401,9 @@ moduleAlias.addAlias('vue-template-compiler', '@dcloudio/vue-cli-plugin-uni/pack
moduleAlias.addAlias('@megalo/template-compiler', '@dcloudio/vue-cli-plugin-uni/packages/@megalo/template-compiler')
moduleAlias.addAlias('mpvue-template-compiler', '@dcloudio/vue-cli-plugin-uni/packages/mpvue-template-compiler')
// vue-loader
moduleAlias.addAlias('vue-loader', '@dcloudio/vue-cli-plugin-uni/packages/vue-loader')
moduleAlias.addAlias('vue-loader', '@dcloudio/vue-cli-plugin-uni/packages/vue-loader')
// sass-loader
moduleAlias.addAlias('sass-loader', '@dcloudio/vue-cli-plugin-uni/packages/sass-loader')
if (process.env.UNI_USING_V3 && process.env.UNI_PLATFORM === 'app-plus') {
moduleAlias.addAlias('./runtime/getUrl.js', '@dcloudio/vue-cli-plugin-uni/lib/app-plus/getUrl.js')
......
......@@ -193,8 +193,6 @@ module.exports = {
alias['vue-i18n'] = require.resolve('@dcloudio/vue-cli-plugin-uni/packages/vue3/node_modules/vue-i18n')
alias['@dcloudio/uni-app'] = require.resolve('@dcloudio/vue-cli-plugin-uni/packages/uni-app')
} else {
alias.vuex = require.resolve('@dcloudio/vue-cli-plugin-uni/packages/vuex3')
}
return {
......
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [8.0.2](https://github.com/webpack-contrib/sass-loader/compare/v8.0.1...v8.0.2) (2020-01-13)
### Bug Fixes
* compatibility with node@8 ([#798](https://github.com/webpack-contrib/sass-loader/issues/798)) ([6f3852f](https://github.com/webpack-contrib/sass-loader/commit/6f3852f7d393dd0bc8f8d264d81ecc941bc72511))
### [8.0.1](https://github.com/webpack-contrib/sass-loader/compare/v8.0.0...v8.0.1) (2020-01-10)
### Bug Fixes
* support webpack@5 ([#794](https://github.com/webpack-contrib/sass-loader/issues/794)) ([6c59e37](https://github.com/webpack-contrib/sass-loader/commit/6c59e37e3f67668d7a3908444ddfc0176bc5601f))
## [8.0.0](https://github.com/webpack-contrib/sass-loader/compare/v7.3.1...v8.0.0) (2019-08-29)
### ⚠ BREAKING CHANGES
* minimum required `webpack` version is `4.36.0`
* minimum required `node.js` version is `8.9.0`
* move all sass (`includePaths`, `importer`, `functions`, `outputStyle`) options to the `sassOptions` option. The `functions` option can't be used as `Function`, you should use `sassOption` as `Function` to achieve this.
* the `data` option was renamed to the `prependData` option
* default value of the `sourceMap` option depends on the `devtool` value (`eval`/`false` values don't enable source map generation)
### Features
* automatically use the `fibers` package if it is possible ([#744](https://github.com/webpack-contrib/sass-loader/issues/744)) ([96184e1](https://github.com/webpack-contrib/sass-loader/commit/96184e1))
* source map generation depends on the `devtool` option ([#743](https://github.com/webpack-contrib/sass-loader/issues/743)) ([fcea88e](https://github.com/webpack-contrib/sass-loader/commit/fcea88e))
* validate loader options ([#737](https://github.com/webpack-contrib/sass-loader/issues/737)) ([7b543fc](https://github.com/webpack-contrib/sass-loader/commit/7b543fc))
* reworked error handling from `node-sass`/`sass`
* improve resolution for `@import` (including support `_index` and `index` files in a directory)
### Bug Fixes
* compatibility with `pnp`
### [7.3.1](https://github.com/webpack-contrib/sass-loader/compare/v7.3.0...v7.3.1) (2019-08-20)
### Bug Fixes
* minimum `node` version in `package.json` ([#733](https://github.com/webpack-contrib/sass-loader/issues/733)) ([1175920](https://github.com/webpack-contrib/sass-loader/commit/1175920))
## [7.3.0](https://github.com/webpack-contrib/sass-loader/compare/v7.2.0...v7.3.0) (2019-08-20)
### Bug Fixes
* handle module import ending `/` as module ([#728](https://github.com/webpack-contrib/sass-loader/issues/728)) ([997a255](https://github.com/webpack-contrib/sass-loader/commit/997a255))
* resolution algorithm ([#720](https://github.com/webpack-contrib/sass-loader/issues/720)) ([0e94940](https://github.com/webpack-contrib/sass-loader/commit/0e94940))
* use "compressed" output when mode is "production" ([#723](https://github.com/webpack-contrib/sass-loader/issues/723)) ([b2af379](https://github.com/webpack-contrib/sass-loader/commit/b2af379))
### Features
* `webpackImporter` option ([#732](https://github.com/webpack-contrib/sass-loader/issues/732)) ([6f4ea37](https://github.com/webpack-contrib/sass-loader/commit/6f4ea37))
<a name="7.2.0"></a>
# [7.2.0](https://github.com/webpack-contrib/sass-loader/compare/v7.1.0...v7.2.0) (2019-08-08)
### Bug Fixes
* better handle stdin in sources ([#681](https://github.com/webpack-contrib/sass-loader/issues/681)) ([e279f2a](https://github.com/webpack-contrib/sass-loader/commit/e279f2a))
* prefer `sass`/`scss`/`css` extensions ([#711](https://github.com/webpack-contrib/sass-loader/issues/711)) ([6fc9d4e](https://github.com/webpack-contrib/sass-loader/commit/6fc9d4e))
* relax node engine ([#708](https://github.com/webpack-contrib/sass-loader/issues/708)) ([2a51502](https://github.com/webpack-contrib/sass-loader/commit/2a51502))
### Features
* allow passing `functions` option as function ([#651](https://github.com/webpack-contrib/sass-loader/issues/651)) ([6c9654d](https://github.com/webpack-contrib/sass-loader/commit/6c9654d))
* support `data` as `Function` ([#648](https://github.com/webpack-contrib/sass-loader/issues/648)) ([aa64e1b](https://github.com/webpack-contrib/sass-loader/commit/aa64e1b))
* support `sass` and `style` fields in `package.json` ([#647](https://github.com/webpack-contrib/sass-loader/issues/647)) ([a8709c9](https://github.com/webpack-contrib/sass-loader/commit/a8709c9))
* support auto resolving `dart-sass` ([ff90dd6](https://github.com/webpack-contrib/sass-loader/commit/ff90dd6))
<a name="7.1.0"></a>
# [7.1.0](https://github.com/webpack-contrib/sass-loader/compare/v7.0.3...v7.1.0) (2018-08-01)
### Features
* Make this package implementation-agnostic (#573) ([bed9fb5](https://github.com/webpack-contrib/sass-loader/commit/bed9fb5)), closes [#435](https://github.com/webpack-contrib/sass-loader/issues/435)
<a name="7.0.3"></a>
## [7.0.3](https://github.com/webpack-contrib/sass-loader/compare/v7.0.2...v7.0.3) (2018-06-05)
### Bug Fixes
* Bare imports not working sometimes (#579) ([c348281](https://github.com/webpack-contrib/sass-loader/commit/c348281)), closes [#566](https://github.com/webpack-contrib/sass-loader/issues/566)
<a name="7.0.2"></a>
## [7.0.2](https://github.com/webpack-contrib/sass-loader/compare/v7.0.1...v7.0.2) (2018-06-02)
### Bug Fixes
* Errors being swallowed when trying to load node-sass (#576) ([6dfb274](https://github.com/webpack-contrib/sass-loader/commit/6dfb274)), closes [#563](https://github.com/webpack-contrib/sass-loader/issues/563)
* Report error to user for problems loading node-sass (#562) ([2529c07](https://github.com/webpack-contrib/sass-loader/commit/2529c07))
<a name="7.0.1"></a>
## [7.0.1](https://github.com/webpack-contrib/sass-loader/compare/v7.0.0...v7.0.1) (2018-04-13)
### Bug Fixes
* Wrong import precedence (#557) ([f4eeff1](https://github.com/webpack-contrib/sass-loader/commit/f4eeff1))
<a name="7.0.0"></a>
# [7.0.0](https://github.com/webpack-contrib/sass-loader/compare/v6.0.7...v7.0.0) (2018-04-13)
### Features
* Refactor resolving and simplify webpack config aliases (#479) ([e0fde1a](https://github.com/webpack-contrib/sass-loader/commit/e0fde1a))
* Remove `node-sass` from `peerDependencies` (#533) ([6439cef](https://github.com/webpack-contrib/sass-loader/commit/6439cef))
### BREAKING CHANGES
* Drop official node 4 support
* This slightly changes the resolving algorithm. Should not break in normal usage, but might break in complex configurations.
* The sass-loader throws an error at runtime now and refuses to compile if the peer dependency is wrong. This could break applications where npm's peer dependency warning was just ignored.
<a name="6.0.7"></a>
## [6.0.7](https://github.com/webpack-contrib/sass-loader/compare/v6.0.6...v6.0.7) (2018-03-03)
### Bug Fixes
* **package:** add `webpack >= v4.0.0` (`peerDependencies`) ([#541](https://github.com/webpack-contrib/sass-loader/issues/541)) ([620bdd4](https://github.com/webpack-contrib/sass-loader/commit/620bdd4))
### Performance Improvements
* use `neo-async` instead `async` ([#538](https://github.com/webpack-contrib/sass-loader/issues/538)) ([fab89dc](https://github.com/webpack-contrib/sass-loader/commit/fab89dc))
<a name="6.0.6"></a>
## [6.0.6](https://github.com/webpack-contrib/sass-loader/compare/v6.0.5...v6.0.6) (2017-06-14)
### Chore
* Adds Webpack 3.x version range to peerDependencies
<a name="6.0.5"></a>
# [6.0.5](https://github.com/webpack-contrib/sass-loader/compare/v6.0.5...v6.0.4) (2017-05-10)
### Bug Fixes
* importing file directly from scoped npm package [#450](https://github.com/webpack-contrib/sass-loader/pull/450) ([5d06e9d](https://github.com/webpack-contrib/sass-loader/commit/5d06e9d))
<a name="6.0.4"></a>
# [6.0.4](https://github.com/webpack-contrib/sass-loader/compare/v6.0.4...v6.0.3) (2017-05-09)
### Bug Fixes
* fix: Resolving of scoped npm packages [#447](https://github.com/webpack-contrib/sass-loader/pull/447)
<a name="6.0.3"></a>
# [6.0.3](https://github.com/webpack-contrib/sass-loader/compare/v6.0.3...v6.0.2) (2017-03-07)
### Bug Fixes
* Fix regression with empty files [#398](https://github.com/webpack-contrib/sass-loader/pull/398)
### Chore
* Reduce npm package size by using the [files](https://docs.npmjs.com/files/package.json#files) property in the `package.json`
<a name="6.0.2"></a>
# [6.0.2](https://github.com/webpack-contrib/sass-loader/compare/v6.0.2...v6.0.1) (2017-02-21)
### Chore
* Update dependencies [#383](https://github.com/webpack-contrib/sass-loader/pull/383)
<a name="6.0.1"></a>
# [6.0.1](https://github.com/webpack-contrib/sass-loader/compare/v6.0.1...v6.0.0) (2017-02-17)
### Bug Fixes
* Fix source maps in certain CWDs. [#377](https://github.com/webpack-contrib/sass-loader/pull/377)
<a name="6.0.0"></a>
# [6.0.0](https://github.com/webpack-contrib/sass-loader/compare/v6.0.0...v5.0.1) (2017-02-13)
### Bug Fixes
* Improve source map support. [#374](https://github.com/webpack-contrib/sass-loader/issues/374)
### BREAKING CHANGES
* This is breaking for the resolve-url-loader
<a name="5.0.1"></a>
# [5.0.1](https://github.com/webpack-contrib/sass-loader/compare/v5.0.1...v5.0.0) (2017-02-13)
### Bug Fixes
* Fix bug where multiple compilations interfered with each other. [#369](https://github.com/webpack-contrib/sass-loader/pull/369)
<a name="5.0.0"></a>
# [5.0.0](https://github.com/webpack-contrib/sass-loader/compare/v5.0.0...v4.1.1) (2017-02-13)
### Code Refactoring
* Remove synchronous compilation support [#334](https://github.com/webpack-contrib/sass-loader/pull/334)
### BREAKING CHANGES
* Remove node 0.12 support. [29b30755021a834e622bf4b5bb9db4d6e5913905](https://github.com/webpack-contrib/sass-loader/commit/29b30755021a834e622bf4b5bb9db4d6e5913905)
* Remove official node-sass@3 and webpack@1 support. [5a6bcb96d8bd7a7a11c33252ba739ffe09ca38c5](https://github.com/webpack-contrib/sass-loader/commit/5a6bcb96d8bd7a7a11c33252ba739ffe09ca38c5)
* Remove synchronous compilation support. [#334](https://github.com/webpack-contrib/sass-loader/pull/334)
<a name="4.1.1"></a>
# [4.1.1](https://github.com/webpack-contrib/sass-loader/compare/v4.1.1...v4.1.0) (2016-12-21)
### Chore
* Update webpack peer dependency to support 2.2.0rc. [#330](https://github.com/webpack-contrib/sass-loader/pull/330)
<a name="4.1.0"></a>
# [4.1.0](https://github.com/webpack-contrib/sass-loader/compare/v4.1.0...v4.0.2) (2016-12-14)
### Features
* Update `node-sass@4.0.0` [#319](https://github.com/webpack-contrib/sass-loader/pull/319)
<a name="4.0.2"></a>
# [4.0.2](https://github.com/webpack-contrib/sass-loader/compare/v4.0.2...v4.0.1) (2016-07-07)
### Bug Fixes
* Fix wrong context in customImporters [#281](https://github.com/webpack-contrib/sass-loader/pull/281)
<a name="4.0.1"></a>
# [4.0.1](https://github.com/webpack-contrib/sass-loader/compare/v4.0.1...v4.0.0) (2016-07-01)
### Bug Fixes
* Fix custom importers receiving `'stdin'` as second argument instead of the actual `resourcePath` [#267](https://github.com/webpack-contrib/sass-loader/pull/267)
<a name="4.0.0"></a>
# [4.0.0](https://github.com/webpack-contrib/sass-loader/compare/v4.0.0...v3.2.2) (2016-06-27)
### Bug Fixes
* Fix incorrect source map paths [#250](https://github.com/webpack-contrib/sass-loader/pull/250)
### BREAKING CHANGES
* Release new major version because the previous release was a breaking change in certain scenarios
See: https://github.com/webpack-contrib/sass-loader/pull/250#issuecomment-228663059
<a name="3.2.2"></a>
# [3.2.2](https://github.com/webpack-contrib/sass-loader/compare/v3.2.2...v3.2.1) (2016-06-26)
### Bug Fixes
* Fix incorrect source map paths [#250](https://github.com/webpack-contrib/sass-loader/pull/250)
<a name="3.2.1"></a>
# [3.2.1](https://github.com/webpack-contrib/sass-loader/compare/v3.2.1...v3.2.0) (2016-06-19)
### Bug Fixes
* Add `webpack@^2.1.0-beta` as peer dependency [#233](https://github.com/webpack-contrib/sass-loader/pull/233)
<a name="3.2.0"></a>
# [3.2.0](https://github.com/webpack-contrib/sass-loader/compare/v3.2.0...v3.1.2) (2016-03-12)
### Features
* Append file content instead of overwriting when `data`-option is already present [#216](https://github.com/webpack-contrib/sass-loader/pull/216)
* Make `indentedSyntax` option a bit smarter [#196](https://github.com/webpack-contrib/sass-loader/pull/196)
<a name="3.1.2"></a>
# [3.1.2](https://github.com/webpack-contrib/sass-loader/compare/v3.1.2...v3.1.1) (2015-11-22)
### Bug Fixes
* Fix loader query not overriding webpack config [#189](https://github.com/webpack-contrib/sass-loader/pull/189)
* Update peer-dependencies [#182](https://github.com/webpack-contrib/sass-loader/pull/182)
- `node-sass^3.4.2`
- `webpack^1.12.6`
<a name="3.1.1"></a>
# [3.1.1](https://github.com/webpack-contrib/sass-loader/compare/v3.1.1...v3.1.0) (2015-10-26)
### Bug Fixes
* Fix missing module `object-assign` [#178](https://github.com/webpack-contrib/sass-loader/issues/178)
<a name="3.1.0"></a>
# [3.1.0](https://github.com/webpack-contrib/sass-loader/compare/v3.1.0...v3.0.0) (2015-10-25)
### Bug Fixes
* Fix a problem where modules with a `.` in their names were not resolved [#167](https://github.com/webpack-contrib/sass-loader/issues/167)
### Features
* Add possibility to also define all options in your `webpack.config.js` [#152](https://github.com/webpack-contrib/sass-loader/pull/152) [#170](https://github.com/webpack-contrib/sass-loader/pull/170)
<a name="3.0.0"></a>
# [3.0.0](https://github.com/webpack-contrib/sass-loader/compare/v3.0.0...v2.0.1) (2015-09-29)
### Bug Fixes
* Fix crash when Sass reported an error without `file` [#158](https://github.com/webpack-contrib/sass-loader/pull/158)
### BREAKING CHANGES
* Add `node-sass@^3.3.3` and `webpack@^1.12.2` as peer-dependency [#165](https://github.com/webpack-contrib/sass-loader/pull/165) [#166](https://github.com/webpack-contrib/sass-loader/pull/166) [#169](https://github.com/webpack-contrib/sass-loader/pull/169)
<a name="2.0.1"></a>
# [2.0.1](https://github.com/webpack-contrib/sass-loader/compare/v2.0.1...v2.0.0) (2015-08-14)
### Bug Fixes
* Add missing path normalization (fixes [#141](https://github.com/webpack-contrib/sass-loader/pull/141))
<a name="2.0.0"></a>
# [2.0.0](https://github.com/webpack-contrib/sass-loader/compare/v2.0.0...v1.0.4) (2015-08-06)
### Bug Fixes
* Add temporary fix for stuck processes (see [sass/node-sass#857](https://github.com/sass/node-sass/issues/857)) [#100](https://github.com/webpack-contrib/sass-loader/issues/100) [#119](https://github.com/webpack-contrib/sass-loader/issues/119) [#132](https://github.com/webpack-contrib/sass-loader/pull/132)
* Fix path resolving on Windows [#108](https://github.com/webpack-contrib/sass-loader/issues/108)
* Fix file watchers on Windows [#102](https://github.com/webpack-contrib/sass-loader/issues/102)
* Fix file watchers for files with errors [#134](https://github.com/webpack-contrib/sass-loader/pull/134)
### Code Refactoring
* Refactor [import resolving algorithm](https://github.com/webpack-contrib/sass-loader/blob/089c52dc9bd02ec67fb5c65c2c226f43710f231c/index.js#L293-L348). ([#138](https://github.com/webpack-contrib/sass-loader/issues/138)) ([c8621a1](https://github.com/webpack-contrib/sass-loader/commit/80944ccf09cd9716a100160c068d255c5d742338))
### BREAKING CHANGES
* The new algorithm is aligned to libsass' way of resolving files. This yields to different results if two files with the same path and filename but with different extensions are present. Though this change should be no problem for most users, we must flag it as breaking change. [#135](https://github.com/webpack-contrib/sass-loader/issues/135) [#138](https://github.com/webpack-contrib/sass-loader/issues/138)
<a name="1.0.4"></a>
# [1.0.4](https://github.com/webpack-contrib/sass-loader/compare/v1.0.4...v1.0.3) (2015-08-03)
### Bug Fixes
* Fix wrong source-map urls [#123](https://github.com/webpack-contrib/sass-loader/pull/123)
* Include source-map contents by default [#104](https://github.com/webpack-contrib/sass-loader/pull/104)
<a name="1.0.3"></a>
# [1.0.3](https://github.com/webpack-contrib/sass-loader/compare/v1.0.3...v1.0.2) (2015-07-22)
### Bug Fixes
* Fix importing css files from scss/sass [#101](https://github.com/webpack-contrib/sass-loader/issues/101)
* Fix importing Sass partials from includePath [#98](https://github.com/webpack-contrib/sass-loader/issues/98) [#110](https://github.com/webpack-contrib/sass-loader/issues/110)
<a name="1.0.2"></a>
# [1.0.2](https://github.com/webpack-contrib/sass-loader/compare/v1.0.2...v1.0.1) (2015-04-15)
### Bug Fixes
* Fix a bug where files could not be imported across language styles [#73](https://github.com/webpack-contrib/sass-loader/issues/73)
* Update peer-dependency `node-sass` to `3.1.0`
<a name="1.0.1"></a>
# [1.0.1](https://github.com/webpack-contrib/sass-loader/compare/v1.0.1...v1.0.0) (2015-03-31)
### Bug Fixes
* Fix Sass partials not being resolved anymore [#68](https://github.com/webpack-contrib/sass-loader/issues/68)
* Update peer-dependency `node-sass` to `3.0.0-beta.4`
<a name="1.0.0"></a>
# [1.0.0](https://github.com/webpack-contrib/sass-loader/compare/v1.0.0...v0.3.1) (2015-03-22)
### Bug Fixes
* Moved `node-sass^3.0.0-alpha.0` to `peerDependencies` [#28](https://github.com/webpack-contrib/sass-loader/issues/28)
* Using webpack's module resolver as custom importer [#39](https://github.com/webpack-contrib/sass-loader/issues/31)
* Add synchronous compilation support for usage with [enhanced-require](https://github.com/webpack/enhanced-require) [#39](https://github.com/webpack-contrib/sass-loader/pull/39)
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
<div align="center">
<img height="100"
src="https://worldvectorlogo.com/logos/sass-1.svg">
<a href="https://github.com/webpack/webpack">
<img width="200" height="200"
src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
</div>
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
[![size][size]][size-url]
# sass-loader
Loads a Sass/SCSS file and compiles it to CSS.
## Getting Started
To begin, you'll need to install `sass-loader`:
```console
npm install sass-loader node-sass webpack --save-dev
```
`sass-loader` requires you to install either [Node Sass](https://github.com/sass/node-sass) or [Dart Sass](https://github.com/sass/dart-sass) on your own (more documentation can be found below).
This allows you to control the versions of all your dependencies, and to choose which Sass implementation to use.
Chain the `sass-loader` with the [css-loader](https://github.com/webpack-contrib/css-loader) and the [style-loader](https://github.com/webpack-contrib/style-loader) to immediately apply all styles to the DOM or the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) to extract it into a separate file.
Then add the loader to your Webpack configuration. For example:
**app.js**
```js
import './style.scss';
```
**style.scss**
```scss
$body-color: red;
body {
color: $body-color;
}
```
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
],
},
};
```
Finally run `webpack` via your preferred method.
### Resolving `import` at-rules
Webpack provides an [advanced mechanism to resolve files](https://webpack.js.org/concepts/module-resolution/).
The `sass-loader` uses Sass's custom importer feature to pass all queries to the Webpack resolving engine. Thus you can import your Sass modules from `node_modules`. Just prepend them with a `~` to tell Webpack that this is not a relative import:
```scss
@import '~bootstrap';
```
It's important to only prepend it with `~`, because `~/` resolves to the home directory.
Webpack needs to distinguish between `bootstrap` and `~bootstrap` because CSS and Sass files have no special syntax for importing relative files.
Writing `@import "style.scss"` is the same as `@import "./style.scss";`
### Problems with `url(...)`
Since Sass implementations don't provide [url rewriting](https://github.com/sass/libsass/issues/532), all linked assets must be relative to the output.
- If you pass the generated CSS on to the `css-loader`, all urls must be relative to the entry-file (e.g. `main.scss`).
- If you're just generating CSS without passing it to the `css-loader`, it must be relative to your web root.
You will be disrupted by this first issue. It is natural to expect relative references to be resolved against the `.sass`/`.scss` file in which they are specified (like in regular `.css` files).
Thankfully there are a two solutions to this problem:
- Add the missing url rewriting using the [resolve-url-loader](https://github.com/bholloway/resolve-url-loader). Place it before `sass-loader` in the loader chain.
- Library authors usually provide a variable to modify the asset path. [bootstrap-sass](https://github.com/twbs/bootstrap-sass) for example has an `$icon-font-path`.
## Options
### `implementation`
The special `implementation` option determines which implementation of Sass to use.
By default the loader resolve the implementation based on your dependencies.
Just add required implementation to `package.json` (`node-sass` or `sass` package) and install dependencies.
Example where the `sass-loader` loader uses the `sass` (`dart-sass`) implementation:
**package.json**
```json
{
"devDependencies": {
"sass-loader": "^7.2.0",
"sass": "^1.22.10"
}
}
```
Example where the `sass-loader` loader uses the `node-sass` implementation:
**package.json**
```json
{
"devDependencies": {
"sass-loader": "^7.2.0",
"node-sass": "^4.0.0"
}
}
```
Beware the situation when `node-sass` and `sass` were installed! By default the `sass-loader` prefers `node-sass`. In order to avoid this situation you can use the `implementation` option.
The `implementation` options either accepts `node-sass` or `sass` (`Dart Sass`) as a module.
For example, to use Dart Sass, you'd pass:
```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
// Prefer `dart-sass`
implementation: require('sass'),
},
},
],
},
],
},
};
```
Note that when using `sass` (`Dart Sass`), **synchronous compilation is twice as fast as asynchronous compilation** by default, due to the overhead of asynchronous callbacks.
To avoid this overhead, you can use the [fibers](https://www.npmjs.com/package/fibers) package to call asynchronous importers from the synchronous code path.
We automatically inject the [`fibers`](https://github.com/laverdet/node-fibers) package (setup `sassOptions.fiber`) if is possible (i.e. you need install the [`fibers`](https://github.com/laverdet/node-fibers) package).
**package.json**
```json
{
"devDependencies": {
"sass-loader": "^7.2.0",
"sass": "^1.22.10",
"fibers": "^4.0.1"
}
}
```
You can disable automatically injecting the [`fibers`](https://github.com/laverdet/node-fibers) package by passing a `false` value for the `sassOptions.fiber` option.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
sassOptions: {
fiber: false,
},
},
},
],
},
],
},
};
```
You can also pass the `fiber` value using this code:
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
sassOptions: {
fiber: require('fibers'),
},
},
},
],
},
],
},
};
```
### `sassOptions`
Type: `Object|Function`
Options for [Node Sass](https://github.com/sass/node-sass) or [Dart Sass](http://sass-lang.com/dart-sass) implementation.
> ℹ️ The `indentedSyntax` option has `true` value for the `sass` extension.
> ℹ️ Options such as `file` and `outFile` are unavailable.
> ℹ We recommend not to use the `sourceMapContents`, `sourceMapEmbed`, `sourceMapRoot` options because `sass-loader` automatically sets these options.
There is a slight difference between the `node-sass` and `sass` (`Dart Sass`) options.
Please consult documentation before using them:
- [Node Sass documentation](https://github.com/sass/node-sass/#options) for all available `node-sass` options.
- [Dart Sass documentation](https://github.com/sass/dart-sass#javascript-api) for all available `sass` options.
#### `Object`
Use and object for the Sass implementation setup.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
sassOptions: {
indentWidth: 4,
includePaths: ['absolute/path/a', 'absolute/path/b'],
},
},
},
],
},
],
},
};
```
#### `Function`
Allows to setup the Sass implementation by setting different options based on the loader context.
```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
sassOptions: (loaderContext) => {
// More information about available properties https://webpack.js.org/api/loaders/
const { resourcePath, rootContext } = loaderContext;
const relativePath = path.relative(rootContext, resourcePath);
if (relativePath === 'styles/foo.scss') {
return {
includePaths: ['absolute/path/c', 'absolute/path/d'],
};
}
return {
includePaths: ['absolute/path/a', 'absolute/path/b'],
};
},
},
},
],
},
],
},
};
```
### `prependData`
Type: `String|Function`
Default: `undefined`
Prepends `Sass`/`SCSS` code before the actual entry file.
In this case, the `sass-loader` will not override the `data` option but just append the entry's content.
This is especially useful when some of your Sass variables depend on the environment:
> ℹ Since you're injecting code, this will break the source mappings in your entry file. Often there's a simpler solution than this, like multiple Sass entry files.
#### `String`
```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
prependData: '$env: ' + process.env.NODE_ENV + ';',
},
},
],
},
],
},
};
```
#### `Function`
```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
prependData: (loaderContext) => {
// More information about available properties https://webpack.js.org/api/loaders/
const { resourcePath, rootContext } = loaderContext;
const relativePath = path.relative(rootContext, resourcePath);
if (relativePath === 'styles/foo.scss') {
return '$value: 100px;';
}
return '$value: 200px;';
},
},
},
],
},
],
},
};
```
### `sourceMap`
Type: `Boolean`
Default: depends on the `compiler.devtool` value
Enables/Disables generation of source maps.
By default generation of source maps depends on the [`devtool`](https://webpack.js.org/configuration/devtool/) option. All values enable source map generation except `eval` and `false` value.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
],
},
};
```
> ℹ In some rare cases `node-sass` can output invalid source maps (it is a `node-sass` bug).
> In order to avoid this, you can try to update `node-sass` to latest version or you can try to set within `sassOptions` the `outputStyle` option to `compressed`.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
sourceMap: true,
sassOptions: {
outputStyle: 'compressed',
},
},
],
},
],
},
};
```
### `webpackImporter`
Type: `Boolean`
Default: `true`
Enables/Disables the default Webpack importer.
This can improve performance in some cases. Use it with caution because aliases and `@import` at-rules starting with `~` will not work. You can pass own `importer` to solve this (see [`importer docs`](https://github.com/sass/node-sass#importer--v200---experimental)).
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
webpackImporter: false,
},
},
],
},
],
},
};
```
## Examples
### Extracts CSS into separate files
For production builds it's recommended to extract the CSS from your bundle being able to use parallel loading of CSS/JS resources later on.
There are two possibilities to extract a style sheet from the bundle:
- [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) (use this, when using webpack 4 configuration. Works in all use-cases)
- [extract-loader](https://github.com/peerigon/extract-loader) (simpler, but specialized on the css-loader's output)
**webpack.config.js**
```js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
// fallback to style-loader in development
process.env.NODE_ENV !== 'production'
? 'style-loader'
: MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader',
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
};
```
### Source maps
Enables/Disables generation of source maps.
To enable CSS source maps, you'll need to pass the `sourceMap` option to the `sass-loader` _and_ the css-loader.
**webpack.config.js**
```javascript
module.exports = {
devtool: 'source-map', // any "source-map"-like devtool is possible
module: {
rules: [
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
],
},
};
```
If you want to edit the original Sass files inside Chrome, [there's a good blog post](https://medium.com/@toolmantim/getting-started-with-css-sourcemaps-and-in-browser-sass-editing-b4daab987fb0). Checkout [test/sourceMap](https://github.com/webpack-contrib/sass-loader/tree/master/test) for a running example.
## Contributing
Please take a moment to read our contributing guidelines if you haven't yet done so.
[CONTRIBUTING](./.github/CONTRIBUTING.md)
## License
[MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/sass-loader.svg
[npm-url]: https://npmjs.com/package/sass-loader
[node]: https://img.shields.io/node/v/sass-loader.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack-contrib/sass-loader.svg
[deps-url]: https://david-dm.org/webpack-contrib/sass-loader
[tests]: https://dev.azure.com/webpack-contrib/sass-loader/_apis/build/status/webpack-contrib.sass-loader?branchName=master
[tests-url]: https://dev.azure.com/webpack-contrib/sass-loader/_build/latest?definitionId=21&branchName=master
[cover]: https://codecov.io/gh/webpack-contrib/sass-loader/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/sass-loader
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[size]: https://packagephobia.now.sh/badge?p=css-loader
[size-url]: https://packagephobia.now.sh/result?p=css-loader
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
class SassError extends Error {
constructor(sassError, resourcePath) {
super();
this.name = 'SassError';
this.originalSassError = sassError;
this.loc = {
line: sassError.line,
column: sassError.column
}; // Keep original error if `sassError.formatted` is unavailable
this.message = `${this.name}: ${this.originalSassError.message}`;
if (this.originalSassError.formatted) {
this.message = `${this.name}: ${this.originalSassError.formatted.replace(/^Error: /, '').replace(/(\s*)stdin(\s*)/, `$1${resourcePath}$2`)}`; // Instruct webpack to hide the JS stack from the console.
// Usually you're only interested in the SASS stack in this case.
// eslint-disable-next-line no-param-reassign
this.hideStack = true;
Error.captureStackTrace(this, this.constructor);
}
}
}
var _default = SassError;
exports.default = _default;
\ No newline at end of file
"use strict";
const loader = require('./index');
module.exports = loader.default;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function getDefaultSassImplementation() {
let sassImplPkg = 'node-sass';
try {
require.resolve('node-sass');
} catch (error) {
try {
require.resolve('sass');
sassImplPkg = 'sass';
} catch (ignoreError) {
sassImplPkg = 'node-sass';
}
} // eslint-disable-next-line import/no-dynamic-require, global-require
return require(sassImplPkg);
}
var _default = getDefaultSassImplementation;
exports.default = _default;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _neoAsync = _interopRequireDefault(require("neo-async"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
let nodeSassJobQueue = null;
/**
* Verifies that the implementation and version of Sass is supported by this loader.
*
* @param {Object} implementation
* @returns {Function}
*/
function getRenderFunctionFromSassImplementation(implementation) {
const isDartSass = implementation.info.includes('dart-sass');
if (isDartSass) {
return implementation.render.bind(implementation);
} // There is an issue with node-sass when async custom importers are used
// See https://github.com/sass/node-sass/issues/857#issuecomment-93594360
// We need to use a job queue to make sure that one thread is always available to the UV lib
if (nodeSassJobQueue === null) {
const threadPoolSize = Number(process.env.UV_THREADPOOL_SIZE || 4);
nodeSassJobQueue = _neoAsync.default.queue(implementation.render.bind(implementation), threadPoolSize - 1);
}
return nodeSassJobQueue.push.bind(nodeSassJobQueue);
}
var _default = getRenderFunctionFromSassImplementation;
exports.default = _default;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _semver = _interopRequireDefault(require("semver"));
var _getDefaultSassImplementation = _interopRequireDefault(require("./getDefaultSassImplementation"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function getSassImplementation(implementation) {
let resolvedImplementation = implementation;
if (!resolvedImplementation) {
// eslint-disable-next-line no-param-reassign
resolvedImplementation = (0, _getDefaultSassImplementation.default)();
}
const {
info
} = resolvedImplementation;
if (!info) {
throw new Error('Unknown Sass implementation.');
}
const infoParts = info.split('\t');
if (infoParts.length < 2) {
throw new Error(`Unknown Sass implementation "${info}".`);
}
const [implementationName, version] = infoParts;
if (implementationName === 'dart-sass') {
if (!_semver.default.satisfies(version, '^1.3.0')) {
throw new Error(`Dart Sass version ${version} is incompatible with ^1.3.0.`);
}
return resolvedImplementation;
} else if (implementationName === 'node-sass') {
if (!_semver.default.satisfies(version, '^4.0.0')) {
throw new Error(`Node Sass version ${version} is incompatible with ^4.0.0.`);
}
return resolvedImplementation;
}
throw new Error(`Unknown Sass implementation "${implementationName}".`);
}
var _default = getSassImplementation;
exports.default = _default;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _os = _interopRequireDefault(require("os"));
var _path = _interopRequireDefault(require("path"));
var _cloneDeep = _interopRequireDefault(require("clone-deep"));
var _proxyCustomImporters = _interopRequireDefault(require("./proxyCustomImporters"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function isProductionLikeMode(loaderContext) {
return loaderContext.mode === 'production' || !loaderContext.mode || loaderContext.minimize;
}
/**
* Derives the sass options from the loader context and normalizes its values with sane defaults.
*
* @param {object} loaderContext
* @param {object} loaderOptions
* @param {string} content
* @param {object} implementation
* @returns {Object}
*/
function getSassOptions(loaderContext, loaderOptions, content, implementation) {
const options = (0, _cloneDeep.default)(loaderOptions.sassOptions ? typeof loaderOptions.sassOptions === 'function' ? loaderOptions.sassOptions(loaderContext) || {} : loaderOptions.sassOptions : {});
const isDartSass = implementation.info.includes('dart-sass');
if (isDartSass) {
const shouldTryToResolveFibers = !options.fiber && options.fiber !== false;
if (shouldTryToResolveFibers) {
let fibers;
try {
fibers = require.resolve('fibers');
} catch (_error) {// Nothing
}
if (fibers) {
// eslint-disable-next-line global-require, import/no-dynamic-require
options.fiber = require(fibers);
}
} else if (options.fiber === false) {
// Don't pass the `fiber` option for `sass` (`Dart Sass`)
delete options.fiber;
}
} else {
// Don't pass the `fiber` option for `node-sass`
delete options.fiber;
}
options.data = loaderOptions.prependData ? typeof loaderOptions.prependData === 'function' ? loaderOptions.prependData(loaderContext) + _os.default.EOL + content : loaderOptions.prependData + _os.default.EOL + content : content; // opt.outputStyle
if (!options.outputStyle && isProductionLikeMode(loaderContext)) {
options.outputStyle = 'compressed';
}
const useSourceMap = typeof loaderOptions.sourceMap === 'boolean' ? loaderOptions.sourceMap : loaderContext.sourceMap; // opt.sourceMap
// Not using the `this.sourceMap` flag because css source maps are different
// @see https://github.com/webpack/css-loader/pull/40
if (useSourceMap) {
// Deliberately overriding the sourceMap option here.
// node-sass won't produce source maps if the data option is used and options.sourceMap is not a string.
// In case it is a string, options.sourceMap should be a path where the source map is written.
// But since we're using the data option, the source map will not actually be written, but
// all paths in sourceMap.sources will be relative to that path.
// Pretty complicated... :(
options.sourceMap = _path.default.join(process.cwd(), '/sass.map');
if ('sourceMapRoot' in options === false) {
options.sourceMapRoot = process.cwd();
}
if ('omitSourceMapUrl' in options === false) {
// The source map url doesn't make sense because we don't know the output path
// The css-loader will handle that for us
options.omitSourceMapUrl = true;
}
if ('sourceMapContents' in options === false) {
// If sourceMapContents option is not set, set it to true otherwise maps will be empty/null
// when exported by webpack-extract-text-plugin.
options.sourceMapContents = true;
}
}
const {
resourcePath
} = loaderContext;
const ext = _path.default.extname(resourcePath); // If we are compiling sass and indentedSyntax isn't set, automatically set it.
if (ext && ext.toLowerCase() === '.sass' && 'indentedSyntax' in options === false) {
options.indentedSyntax = true;
} else {
options.indentedSyntax = Boolean(options.indentedSyntax);
} // Allow passing custom importers to `node-sass`. Accepts `Function` or an array of `Function`s.
options.importer = options.importer ? (0, _proxyCustomImporters.default)(options.importer, resourcePath) : [];
options.includePaths = (options.includePaths || []).concat(_path.default.dirname(resourcePath));
return options;
}
var _default = getSassOptions;
exports.default = _default;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _path = _interopRequireDefault(require("path"));
var _loaderUtils = _interopRequireDefault(require("loader-utils"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Examples:
// - ~package
// - ~package/
// - ~@org
// - ~@org/
// - ~@org/package
// - ~@org/package/
const matchModuleImport = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;
/**
* When libsass tries to resolve an import, it uses a special algorithm.
* Since the sass-loader uses webpack to resolve the modules, we need to simulate that algorithm. This function
* returns an array of import paths to try. The last entry in the array is always the original url
* to enable straight-forward webpack.config aliases.
*
* @param {string} url
* @returns {Array<string>}
*/
function importsToResolve(url) {
const request = _loaderUtils.default.urlToRequest(url); // Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot.
// @see https://github.com/webpack-contrib/sass-loader/issues/167
const ext = _path.default.extname(request).toLowerCase(); // In case there is module request, send this to webpack resolver
if (matchModuleImport.test(url)) {
return [request, url];
} // Because @import is also defined in CSS, Sass needs a way of compiling plain CSS @imports without trying to import the files at compile time.
// To accomplish this, and to ensure SCSS is as much of a superset of CSS as possible, Sass will compile any @imports with the following characteristics to plain CSS imports:
// - imports where the URL ends with .css.
// - imports where the URL begins http:// or https://.
// - imports where the URL is written as a url().
// - imports that have media queries.
//
// The `node-sass` package sends `@import` ending on `.css` to importer, it is bug, so we skip resolve
if (ext === '.css') {
return [];
}
const dirname = _path.default.dirname(request);
const basename = _path.default.basename(request); // In case there is file extension:
//
// 1. Try to resolve `_` file.
// 2. Try to resolve file without `_`.
// 3. Send a original url to webpack resolver, maybe it is alias.
if (['.scss', '.sass'].includes(ext)) {
return [`${dirname}/_${basename}`, `${dirname}/${basename}`, url];
} // In case there is no file extension and filename starts with `_`:
//
// 1. Try to resolve files with `scss`, `sass` and `css` extensions.
// 2. Try to resolve directory with `_index` or `index` filename.
// 3. Send the original url to webpack resolver, maybe it's alias.
if (basename.startsWith('_')) {
return [`${request}.scss`, `${request}.sass`, `${request}.css`, request, url];
} // In case there is no file extension and filename doesn't start with `_`:
//
// 1. Try to resolve file starts with `_` and with extensions
// 2. Try to resolve file with extensions
// 3. Try to resolve directory with `_index` or `index` filename.
// 4. Send a original url to webpack resolver, maybe it is alias.
return [`${dirname}/_${basename}.scss`, `${dirname}/_${basename}.sass`, `${dirname}/_${basename}.css`, `${request}.scss`, `${request}.sass`, `${request}.css`, request, url];
}
var _default = importsToResolve;
exports.default = _default;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _path = _interopRequireDefault(require("path"));
var _schemaUtils = _interopRequireDefault(require("schema-utils"));
var _loaderUtils = require("loader-utils");
var _options = _interopRequireDefault(require("./options.json"));
var _getSassImplementation = _interopRequireDefault(require("./getSassImplementation"));
var _getSassOptions = _interopRequireDefault(require("./getSassOptions"));
var _webpackImporter = _interopRequireDefault(require("./webpackImporter"));
var _getRenderFunctionFromSassImplementation = _interopRequireDefault(require("./getRenderFunctionFromSassImplementation"));
var _SassError = _interopRequireDefault(require("./SassError"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The sass-loader makes node-sass and dart-sass available to webpack modules.
*
* @this {object}
* @param {string} content
*/
function loader(content) {
const options = (0, _loaderUtils.getOptions)(this) || {};
(0, _schemaUtils.default)(_options.default, options, {
name: 'Sass Loader',
baseDataPath: 'options'
});
const implementation = (0, _getSassImplementation.default)(options.implementation);
const callback = this.async();
const addNormalizedDependency = file => {
// node-sass returns POSIX paths
this.addDependency(_path.default.normalize(file));
};
const sassOptions = (0, _getSassOptions.default)(this, options, content, implementation);
const shouldUseWebpackImporter = typeof options.webpackImporter === 'boolean' ? options.webpackImporter : true;
if (shouldUseWebpackImporter) {
const resolve = this.getResolve({
mainFields: ['sass', 'style', 'main', '...'],
mainFiles: ['_index', 'index', '...'],
extensions: ['.scss', '.sass', '.css', '...']
});
sassOptions.importer.push((0, _webpackImporter.default)(this.resourcePath, resolve, addNormalizedDependency));
} // Skip empty files, otherwise it will stop webpack, see issue #21
if (sassOptions.data.trim() === '') {
callback(null, '');
return;
}
const render = (0, _getRenderFunctionFromSassImplementation.default)(implementation);
render(sassOptions, (error, result) => {
if (error) {
if (error.file) {
addNormalizedDependency(error.file);
}
callback(new _SassError.default(error, this.resourcePath));
return;
}
if (result.map && result.map !== '{}') {
// eslint-disable-next-line no-param-reassign
result.map = JSON.parse(result.map); // result.map.file is an optional property that provides the output filename.
// Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
// eslint-disable-next-line no-param-reassign
delete result.map.file; // One of the sources is 'stdin' according to dart-sass/node-sass because we've used the data input.
// Now let's override that value with the correct relative path.
// Since we specified options.sourceMap = path.join(process.cwd(), "/sass.map"); in getSassOptions,
// we know that this path is relative to process.cwd(). This is how node-sass works.
// eslint-disable-next-line no-param-reassign
const stdinIndex = result.map.sources.findIndex(source => source.includes('stdin'));
if (stdinIndex !== -1) {
// eslint-disable-next-line no-param-reassign
result.map.sources[stdinIndex] = _path.default.relative(process.cwd(), this.resourcePath);
} // node-sass returns POSIX paths, that's why we need to transform them back to native paths.
// This fixes an error on windows where the source-map module cannot resolve the source maps.
// @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722
// eslint-disable-next-line no-param-reassign
result.map.sourceRoot = _path.default.normalize(result.map.sourceRoot); // eslint-disable-next-line no-param-reassign
result.map.sources = result.map.sources.map(_path.default.normalize);
} else {
// eslint-disable-next-line no-param-reassign
result.map = null;
}
result.stats.includedFiles.forEach(addNormalizedDependency);
callback(null, result.css.toString(), result.map);
});
}
var _default = loader;
exports.default = _default;
\ No newline at end of file
{
"type": "object",
"properties": {
"implementation": {
"description": "The implementation of the sass to be used (https://github.com/webpack-contrib/sass-loader#implementation).",
"type": "object"
},
"sassOptions": {
"description": "Options for `node-sass` or `sass` (`Dart Sass`) implementation. (https://github.com/webpack-contrib/sass-loader#implementation).",
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"instanceof": "Function"
}
]
},
"prependData": {
"description": "Prepends `Sass`/`SCSS` code before the actual entry file (https://github.com/webpack-contrib/sass-loader#prependdata).",
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Function"
}
]
},
"sourceMap": {
"description": "Enables/Disables generation of source maps (https://github.com/webpack-contrib/sass-loader#sourcemap).",
"type": "boolean"
},
"webpackImporter": {
"description": "Enables/Disables default `webpack` importer (https://github.com/webpack-contrib/sass-loader#webpackimporter).",
"type": "boolean"
}
},
"additionalProperties": false
}
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/**
* Creates new custom importers that use the given `resourcePath` if libsass calls the custom importer with `prev`
* being 'stdin'.
*
* Why do we need this? We have to use the `data` option of node-sass in order to compile our sass because
* the `resourcePath` might not be an actual file on disk. When using the `data` option, libsass uses the string
* 'stdin' instead of a filename.
*
* We have to fix this behavior in order to provide a consistent experience to the webpack user.
*
* @param {Function|Array<Function>} importer
* @param {string} resourcePath
* @returns {Array<Function>}
*/
function proxyCustomImporters(importer, resourcePath) {
return [].concat(importer).map( // eslint-disable-next-line no-shadow
importer => function customImporter() {
return importer.apply(this, // eslint-disable-next-line prefer-rest-params
Array.from(arguments).map((arg, i) => i === 1 && arg === 'stdin' ? resourcePath : arg));
});
}
var _default = proxyCustomImporters;
exports.default = _default;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _path = _interopRequireDefault(require("path"));
var _importsToResolve = _interopRequireDefault(require("./importsToResolve"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @name PromisedResolve
* @type {Function}
* @param {string} dir
* @param {string} request
* @returns Promise
*/
/**
* @name Importer
* @type {Function}
* @param {string} url
* @param {string} prev
* @param {Function<Error, string>} done
*/
const matchCss = /\.css$/i;
/**
* Returns an importer that uses webpack's resolving algorithm.
*
* It's important that the returned function has the correct number of arguments
* (based on whether the call is sync or async) because otherwise node-sass doesn't exit.
*
* @param {string} resourcePath
* @param {PromisedResolve} resolve
* @param {Function<string>} addNormalizedDependency
* @returns {Importer}
*/
const fs = require('fs')
const preprocessor = require('../../webpack-preprocess-loader/preprocess/lib/preprocess')
const {
cssPreprocessOptions
} = require('@dcloudio/uni-cli-shared')
function webpackImporter(resourcePath, resolve, addNormalizedDependency) {
function dirContextFrom(fileContext) {
return _path.default.dirname( // The first file is 'stdin' when we're using the data option
fileContext === 'stdin' ? resourcePath : fileContext);
} // eslint-disable-next-line no-shadow
function startResolving(dir, importsToResolve) {
return importsToResolve.length === 0 ? Promise.reject() : resolve(dir, importsToResolve[0]).then(resolvedFile => {
// Add the resolvedFilename as dependency. Although we're also using stats.includedFiles, this might come
// in handy when an error occurs. In this case, we don't get stats.includedFiles from node-sass.
addNormalizedDependency(resolvedFile);
const file = resolvedFile.replace(matchCss, '')
if (fs.existsSync(file)) {
const contents = fs.readFileSync(file, 'utf8')
if (contents.includes('#endif')) {
return {
file,
contents: preprocessor.preprocess(contents, cssPreprocessOptions.context, {
type: cssPreprocessOptions.type
})
}
}
}
return {
// By removing the CSS file extension, we trigger node-sass to include the CSS file instead of just linking it.
file: resolvedFile.replace(matchCss, '')
};
}, () => {
const [, ...tailResult] = importsToResolve;
return startResolving(dir, tailResult);
});
}
return (url, prev, done) => {
startResolving(dirContextFrom(prev), (0, _importsToResolve.default)(url)) // Catch all resolving errors, return the original file and pass responsibility back to other custom importers
.catch(() => {
return {
file: url
};
}).then(done);
};
}
var _default = webpackImporter;
exports.default = _default;
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [2.7.0](https://github.com/webpack/schema-utils/compare/v2.6.6...v2.7.0) (2020-05-29)
### Features
* improve hints ([a36e535](https://github.com/webpack/schema-utils/commit/a36e535faca1b01e27c3bfa3c8bee9227c3f836c))
* smart not case ([#101](https://github.com/webpack/schema-utils/issues/101)) ([698d8b0](https://github.com/webpack/schema-utils/commit/698d8b05462d86aadb217e25a45c7b953a79a52e))
### Bug Fixes
* move @types/json-schema from devDependencies to dependencies ([#97](https://github.com/webpack/schema-utils/issues/97)) ([#98](https://github.com/webpack/schema-utils/issues/98)) ([945e67d](https://github.com/webpack/schema-utils/commit/945e67db5e19baf7ec7df72813b0739dd56f950d))
### [2.6.6](https://github.com/webpack/schema-utils/compare/v2.6.5...v2.6.6) (2020-04-17)
### Bug Fixes
* improve perf
### [2.6.5](https://github.com/webpack/schema-utils/compare/v2.6.4...v2.6.5) (2020-03-11)
### Bug Fixes
* correct dots at end of sentence ([7284beb](https://github.com/webpack/schema-utils/commit/7284bebe00cd570f1bef2c15951a07b9794038e6))
### [2.6.4](https://github.com/webpack/schema-utils/compare/v2.6.3...v2.6.4) (2020-01-17)
### Bug Fixes
* change `initialised` to `initialized` ([#87](https://github.com/webpack/schema-utils/issues/87)) ([70f12d3](https://github.com/webpack/schema-utils/commit/70f12d33a8eaa27249bc9c1a27f886724cf91ea7))
### [2.6.3](https://github.com/webpack/schema-utils/compare/v2.6.2...v2.6.3) (2020-01-17)
### Bug Fixes
* prefer the `baseDataPath` option from arguments ([#86](https://github.com/webpack/schema-utils/issues/86)) ([e236859](https://github.com/webpack/schema-utils/commit/e236859e85b28e35e1294f86fc1ff596a5031cea))
### [2.6.2](https://github.com/webpack/schema-utils/compare/v2.6.1...v2.6.2) (2020-01-14)
### Bug Fixes
* better handle Windows absolute paths ([#85](https://github.com/webpack/schema-utils/issues/85)) ([1fa2930](https://github.com/webpack/schema-utils/commit/1fa2930a161e907b9fc53a7233d605910afdb883))
### [2.6.1](https://github.com/webpack/schema-utils/compare/v2.6.0...v2.6.1) (2019-11-28)
### Bug Fixes
* typescript declarations ([#84](https://github.com/webpack/schema-utils/issues/84)) ([89d55a9](https://github.com/webpack/schema-utils/commit/89d55a9a8edfa6a8ac8b112f226bb3154e260319))
## [2.6.0](https://github.com/webpack/schema-utils/compare/v2.5.0...v2.6.0) (2019-11-27)
### Features
* support configuration via title ([#81](https://github.com/webpack/schema-utils/issues/81)) ([afddc10](https://github.com/webpack/schema-utils/commit/afddc109f6891cd37a9f1835d50862d119a072bf))
### Bug Fixes
* typescript definitions ([#70](https://github.com/webpack/schema-utils/issues/70)) ([f38158d](https://github.com/webpack/schema-utils/commit/f38158d6d040e2c701622778ae8122fb26a4f990))
## [2.5.0](https://github.com/webpack/schema-utils/compare/v2.4.1...v2.5.0) (2019-10-15)
### Bug Fixes
* rework format for maxLength, minLength ([#67](https://github.com/webpack/schema-utils/issues/67)) ([0d12259](https://github.com/webpack/schema-utils/commit/0d12259))
* support all cases with one number in range ([#64](https://github.com/webpack/schema-utils/issues/64)) ([7fc8069](https://github.com/webpack/schema-utils/commit/7fc8069))
* typescript definition and export naming ([#69](https://github.com/webpack/schema-utils/issues/69)) ([a435b79](https://github.com/webpack/schema-utils/commit/a435b79))
### Features
* "smart" numbers range ([62fb107](https://github.com/webpack/schema-utils/commit/62fb107))
### [2.4.1](https://github.com/webpack/schema-utils/compare/v2.4.0...v2.4.1) (2019-09-27)
### Bug Fixes
* publish definitions ([#58](https://github.com/webpack/schema-utils/issues/58)) ([1885faa](https://github.com/webpack/schema-utils/commit/1885faa))
## [2.4.0](https://github.com/webpack/schema-utils/compare/v2.3.0...v2.4.0) (2019-09-26)
### Features
* better errors when the `type` keyword doesn't exist ([0988be2](https://github.com/webpack/schema-utils/commit/0988be2))
* support $data reference ([#56](https://github.com/webpack/schema-utils/issues/56)) ([d2f11d6](https://github.com/webpack/schema-utils/commit/d2f11d6))
* types definitions ([#52](https://github.com/webpack/schema-utils/issues/52)) ([facb431](https://github.com/webpack/schema-utils/commit/facb431))
## [2.3.0](https://github.com/webpack/schema-utils/compare/v2.2.0...v2.3.0) (2019-09-26)
### Features
* support `not` keyword ([#53](https://github.com/webpack/schema-utils/issues/53)) ([765f458](https://github.com/webpack/schema-utils/commit/765f458))
## [2.2.0](https://github.com/webpack/schema-utils/compare/v2.1.0...v2.2.0) (2019-09-02)
### Features
* better error output for `oneOf` and `anyOf` ([#48](https://github.com/webpack/schema-utils/issues/48)) ([#50](https://github.com/webpack/schema-utils/issues/50)) ([332242f](https://github.com/webpack/schema-utils/commit/332242f))
## [2.1.0](https://github.com/webpack-contrib/schema-utils/compare/v2.0.1...v2.1.0) (2019-08-07)
### Bug Fixes
* throw error on sparse arrays ([#47](https://github.com/webpack-contrib/schema-utils/issues/47)) ([b85ac38](https://github.com/webpack-contrib/schema-utils/commit/b85ac38))
### Features
* export `ValidateError` ([#46](https://github.com/webpack-contrib/schema-utils/issues/46)) ([ff781d7](https://github.com/webpack-contrib/schema-utils/commit/ff781d7))
### [2.0.1](https://github.com/webpack-contrib/schema-utils/compare/v2.0.0...v2.0.1) (2019-07-18)
### Bug Fixes
* error message for empty object ([#44](https://github.com/webpack-contrib/schema-utils/issues/44)) ([0b4b4a2](https://github.com/webpack-contrib/schema-utils/commit/0b4b4a2))
### [2.0.0](https://github.com/webpack-contrib/schema-utils/compare/v1.0.0...v2.0.0) (2019-07-17)
### BREAKING CHANGES
* drop support for Node.js < 8.9.0
* drop support `errorMessage`, please use `description` for links.
* api was changed, please look documentation.
* error messages was fully rewritten.
<a name="1.0.0"></a>
# [1.0.0](https://github.com/webpack-contrib/schema-utils/compare/v0.4.7...v1.0.0) (2018-08-07)
### Features
* **src:** add support for custom error messages ([#33](https://github.com/webpack-contrib/schema-utils/issues/33)) ([1cbe4ef](https://github.com/webpack-contrib/schema-utils/commit/1cbe4ef))
<a name="0.4.7"></a>
## [0.4.7](https://github.com/webpack-contrib/schema-utils/compare/v0.4.6...v0.4.7) (2018-08-07)
### Bug Fixes
* **src:** `node >= v4.0.0` support ([#32](https://github.com/webpack-contrib/schema-utils/issues/32)) ([cb13dd4](https://github.com/webpack-contrib/schema-utils/commit/cb13dd4))
<a name="0.4.6"></a>
## [0.4.6](https://github.com/webpack-contrib/schema-utils/compare/v0.4.5...v0.4.6) (2018-08-06)
### Bug Fixes
* **package:** remove lockfile ([#28](https://github.com/webpack-contrib/schema-utils/issues/28)) ([69f1a81](https://github.com/webpack-contrib/schema-utils/commit/69f1a81))
* **package:** remove unnecessary `webpack` dependency ([#26](https://github.com/webpack-contrib/schema-utils/issues/26)) ([532eaa5](https://github.com/webpack-contrib/schema-utils/commit/532eaa5))
<a name="0.4.5"></a>
## [0.4.5](https://github.com/webpack-contrib/schema-utils/compare/v0.4.4...v0.4.5) (2018-02-13)
### Bug Fixes
* **CHANGELOG:** update broken links ([4483b9f](https://github.com/webpack-contrib/schema-utils/commit/4483b9f))
* **package:** update broken links ([f2494ba](https://github.com/webpack-contrib/schema-utils/commit/f2494ba))
<a name="0.4.4"></a>
## [0.4.4](https://github.com/webpack-contrib/schema-utils/compare/v0.4.3...v0.4.4) (2018-02-13)
### Bug Fixes
* **package:** update `dependencies` ([#22](https://github.com/webpack-contrib/schema-utils/issues/22)) ([3aecac6](https://github.com/webpack-contrib/schema-utils/commit/3aecac6))
<a name="0.4.3"></a>
## [0.4.3](https://github.com/webpack-contrib/schema-utils/compare/v0.4.2...v0.4.3) (2017-12-14)
### Bug Fixes
* **validateOptions:** throw `err` instead of `process.exit(1)` ([#17](https://github.com/webpack-contrib/schema-utils/issues/17)) ([c595eda](https://github.com/webpack-contrib/schema-utils/commit/c595eda))
* **ValidationError:** never return `this` in the ctor ([#16](https://github.com/webpack-contrib/schema-utils/issues/16)) ([c723791](https://github.com/webpack-contrib/schema-utils/commit/c723791))
<a name="0.4.2"></a>
## [0.4.2](https://github.com/webpack-contrib/schema-utils/compare/v0.4.1...v0.4.2) (2017-11-09)
### Bug Fixes
* **validateOptions:** catch `ValidationError` and handle it internally ([#15](https://github.com/webpack-contrib/schema-utils/issues/15)) ([9c5ef5e](https://github.com/webpack-contrib/schema-utils/commit/9c5ef5e))
<a name="0.4.1"></a>
## [0.4.1](https://github.com/webpack-contrib/schema-utils/compare/v0.4.0...v0.4.1) (2017-11-03)
### Bug Fixes
* **ValidationError:** use `Error.captureStackTrace` for `err.stack` handling ([#14](https://github.com/webpack-contrib/schema-utils/issues/14)) ([a6fb974](https://github.com/webpack-contrib/schema-utils/commit/a6fb974))
<a name="0.4.0"></a>
# [0.4.0](https://github.com/webpack-contrib/schema-utils/compare/v0.3.0...v0.4.0) (2017-10-28)
### Features
* add support for `typeof`, `instanceof` (`{Function\|RegExp}`) ([#10](https://github.com/webpack-contrib/schema-utils/issues/10)) ([9f01816](https://github.com/webpack-contrib/schema-utils/commit/9f01816))
<a name="0.3.0"></a>
# [0.3.0](https://github.com/webpack-contrib/schema-utils/compare/v0.2.1...v0.3.0) (2017-04-29)
### Features
* add ValidationError ([#8](https://github.com/webpack-contrib/schema-utils/issues/8)) ([d48f0fb](https://github.com/webpack-contrib/schema-utils/commit/d48f0fb))
<a name="0.2.1"></a>
## [0.2.1](https://github.com/webpack-contrib/schema-utils/compare/v0.2.0...v0.2.1) (2017-03-13)
### Bug Fixes
* Include .babelrc to `files` ([28f0363](https://github.com/webpack-contrib/schema-utils/commit/28f0363))
* Include source to `files` ([43b0f2f](https://github.com/webpack-contrib/schema-utils/commit/43b0f2f))
<a name="0.2.0"></a>
# [0.2.0](https://github.com/webpack-contrib/schema-utils/compare/v0.1.0...v0.2.0) (2017-03-12)
<a name="0.1.0"></a>
# 0.1.0 (2017-03-07)
### Features
* **validations:** add validateOptions module ([ae9b47b](https://github.com/webpack-contrib/schema-utils/commit/ae9b47b))
# Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<div align="center">
<a href="http://json-schema.org">
<img width="160" height="160"
src="https://raw.githubusercontent.com/webpack-contrib/schema-utils/master/.github/assets/logo.png">
</a>
<a href="https://github.com/webpack/webpack">
<img width="200" height="200"
src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
</div>
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
[![size][size]][size-url]
# schema-utils
Package for validate options in loaders and plugins.
## Getting Started
To begin, you'll need to install `schema-utils`:
```console
npm install schema-utils
```
## API
**schema.json**
```json
{
"type": "object",
"properties": {
"option": {
"type": ["boolean"]
}
},
"additionalProperties": false
}
```
```js
import schema from './path/to/schema.json';
import validate from 'schema-utils';
const options = { option: true };
const configuration = { name: 'Loader Name/Plugin Name/Name' };
validate(schema, options, configuration);
```
### `schema`
Type: `String`
JSON schema.
Simple example of schema:
```json
{
"type": "object",
"properties": {
"name": {
"description": "This is description of option.",
"type": "string"
}
},
"additionalProperties": false
}
```
### `options`
Type: `Object`
Object with options.
```js
validate(
schema,
{
name: 123,
},
{ name: 'MyPlugin' }
);
```
### `configuration`
Allow to configure validator.
There is an alternative method to configure the `name` and`baseDataPath` options via the `title` property in the schema.
For example:
```json
{
"title": "My Loader options",
"type": "object",
"properties": {
"name": {
"description": "This is description of option.",
"type": "string"
}
},
"additionalProperties": false
}
```
The last word used for the `baseDataPath` option, other words used for the `name` option.
Based on the example above the `name` option equals `My Loader`, the `baseDataPath` option equals `options`.
#### `name`
Type: `Object`
Default: `"Object"`
Allow to setup name in validation errors.
```js
validate(schema, options, { name: 'MyPlugin' });
```
```shell
Invalid configuration object. MyPlugin has been initialised using a configuration object that does not match the API schema.
- configuration.optionName should be a integer.
```
#### `baseDataPath`
Type: `String`
Default: `"configuration"`
Allow to setup base data path in validation errors.
```js
validate(schema, options, { name: 'MyPlugin', baseDataPath: 'options' });
```
```shell
Invalid options object. MyPlugin has been initialised using an options object that does not match the API schema.
- options.optionName should be a integer.
```
#### `postFormatter`
Type: `Function`
Default: `undefined`
Allow to reformat errors.
```js
validate(schema, options, {
name: 'MyPlugin',
postFormatter: (formattedError, error) => {
if (error.keyword === 'type') {
return `${formattedError}\nAdditional Information.`;
}
return formattedError;
},
});
```
```shell
Invalid options object. MyPlugin has been initialized using an options object that does not match the API schema.
- options.optionName should be a integer.
Additional Information.
```
## Examples
**schema.json**
```json
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"test": {
"anyOf": [
{ "type": "array" },
{ "type": "string" },
{ "instanceof": "RegExp" }
]
},
"transform": {
"instanceof": "Function"
},
"sourceMap": {
"type": "boolean"
}
},
"additionalProperties": false
}
```
### `Loader`
```js
import { getOptions } from 'loader-utils';
import validateOptions from 'schema-utils';
import schema from 'path/to/schema.json';
function loader(src, map) {
const options = getOptions(this) || {};
validateOptions(schema, options, {
name: 'Loader Name',
baseDataPath: 'options',
});
// Code...
}
export default loader;
```
### `Plugin`
```js
import validateOptions from 'schema-utils';
import schema from 'path/to/schema.json';
class Plugin {
constructor(options) {
validateOptions(schema, options, {
name: 'Plugin Name',
baseDataPath: 'options',
});
this.options = options;
}
apply(compiler) {
// Code...
}
}
export default Plugin;
```
## Contributing
Please take a moment to read our contributing guidelines if you haven't yet done so.
[CONTRIBUTING](./.github/CONTRIBUTING.md)
## License
[MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/schema-utils.svg
[npm-url]: https://npmjs.com/package/schema-utils
[node]: https://img.shields.io/node/v/schema-utils.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack/schema-utils.svg
[deps-url]: https://david-dm.org/webpack/schema-utils
[tests]: https://github.com/webpack/schema-utils/workflows/schema-utils/badge.svg
[tests-url]: https://github.com/webpack/schema-utils/actions
[cover]: https://codecov.io/gh/webpack/schema-utils/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack/schema-utils
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[size]: https://packagephobia.now.sh/badge?p=schema-utils
[size-url]: https://packagephobia.now.sh/result?p=schema-utils
export default ValidationError;
export type JSONSchema6 = import('json-schema').JSONSchema6;
export type JSONSchema7 = import('json-schema').JSONSchema7;
export type Schema =
| (import('json-schema').JSONSchema4 & import('./validate').Extend)
| (import('json-schema').JSONSchema6 & import('./validate').Extend)
| (import('json-schema').JSONSchema7 & import('./validate').Extend);
export type ValidationErrorConfiguration = {
name?: string | undefined;
baseDataPath?: string | undefined;
postFormatter?: import('./validate').PostFormatter | undefined;
};
export type PostFormatter = (
formattedError: string,
error: import('ajv').ErrorObject & {
children?: import('ajv').ErrorObject[] | undefined;
}
) => string;
export type SchemaUtilErrorObject = import('ajv').ErrorObject & {
children?: import('ajv').ErrorObject[] | undefined;
};
export type SPECIFICITY = number;
declare class ValidationError extends Error {
/**
* @param {Array<SchemaUtilErrorObject>} errors
* @param {Schema} schema
* @param {ValidationErrorConfiguration} configuration
*/
constructor(
errors: Array<SchemaUtilErrorObject>,
schema: Schema,
configuration?: ValidationErrorConfiguration
);
/** @type {Array<SchemaUtilErrorObject>} */
errors: Array<SchemaUtilErrorObject>;
/** @type {Schema} */
schema: Schema;
/** @type {string} */
headerName: string;
/** @type {string} */
baseDataPath: string;
/** @type {PostFormatter | null} */
postFormatter: PostFormatter | null;
/**
* @param {string} path
* @returns {Schema}
*/
getSchemaPart(path: string): Schema;
/**
* @param {Schema} schema
* @param {boolean} logic
* @param {Array<Object>} prevSchemas
* @returns {string}
*/
formatSchema(
schema: Schema,
logic?: boolean,
prevSchemas?: Array<Object>
): string;
/**
* @param {Schema=} schemaPart
* @param {(boolean | Array<string>)=} additionalPath
* @param {boolean=} needDot
* @param {boolean=} logic
* @returns {string}
*/
getSchemaPartText(
schemaPart?: Schema | undefined,
additionalPath?: (boolean | Array<string>) | undefined,
needDot?: boolean | undefined,
logic?: boolean | undefined
): string;
/**
* @param {Schema=} schemaPart
* @returns {string}
*/
getSchemaPartDescription(schemaPart?: Schema | undefined): string;
/**
* @param {SchemaUtilErrorObject} error
* @returns {string}
*/
formatValidationError(error: SchemaUtilErrorObject): string;
/**
* @param {Array<SchemaUtilErrorObject>} errors
* @returns {string}
*/
formatValidationErrors(errors: Array<SchemaUtilErrorObject>): string;
}
declare const _exports: typeof import('./validate').default;
export = _exports;
export default addAbsolutePathKeyword;
export type Ajv = import('ajv').Ajv;
export type ValidateFunction = import('ajv').ValidateFunction;
export type SchemaUtilErrorObject = import('ajv').ErrorObject & {
children?: import('ajv').ErrorObject[] | undefined;
};
/**
*
* @param {Ajv} ajv
* @returns {Ajv}
*/
declare function addAbsolutePathKeyword(ajv: Ajv): Ajv;
export = Range;
/**
* @typedef {[number, boolean]} RangeValue
*/
/**
* @callback RangeValueCallback
* @param {RangeValue} rangeValue
* @returns {boolean}
*/
declare class Range {
/**
* @param {"left" | "right"} side
* @param {boolean} exclusive
* @returns {">" | ">=" | "<" | "<="}
*/
static getOperator(
side: 'left' | 'right',
exclusive: boolean
): '>' | '>=' | '<' | '<=';
/**
* @param {number} value
* @param {boolean} logic is not logic applied
* @param {boolean} exclusive is range exclusive
* @returns {string}
*/
static formatRight(value: number, logic: boolean, exclusive: boolean): string;
/**
* @param {number} value
* @param {boolean} logic is not logic applied
* @param {boolean} exclusive is range exclusive
* @returns {string}
*/
static formatLeft(value: number, logic: boolean, exclusive: boolean): string;
/**
* @param {number} start left side value
* @param {number} end right side value
* @param {boolean} startExclusive is range exclusive from left side
* @param {boolean} endExclusive is range exclusive from right side
* @param {boolean} logic is not logic applied
* @returns {string}
*/
static formatRange(
start: number,
end: number,
startExclusive: boolean,
endExclusive: boolean,
logic: boolean
): string;
/**
* @param {Array<RangeValue>} values
* @param {boolean} logic is not logic applied
* @return {RangeValue} computed value and it's exclusive flag
*/
static getRangeValue(
values: Array<RangeValue>,
logic: boolean
): [number, boolean];
/** @type {Array<RangeValue>} */
_left: Array<RangeValue>;
/** @type {Array<RangeValue>} */
_right: Array<RangeValue>;
/**
* @param {number} value
* @param {boolean=} exclusive
*/
left(value: number, exclusive?: boolean | undefined): void;
/**
* @param {number} value
* @param {boolean=} exclusive
*/
right(value: number, exclusive?: boolean | undefined): void;
/**
* @param {boolean} logic is not logic applied
* @return {string} "smart" range string representation
*/
format(logic?: boolean): string;
}
declare namespace Range {
export { RangeValue, RangeValueCallback };
}
type RangeValue = [number, boolean];
type RangeValueCallback = (rangeValue: [number, boolean]) => boolean;
export function stringHints(schema: Schema, logic: boolean): string[];
export function numberHints(schema: Schema, logic: boolean): string[];
export type Schema =
| (import('json-schema').JSONSchema4 & import('../validate').Extend)
| (import('json-schema').JSONSchema6 & import('../validate').Extend)
| (import('json-schema').JSONSchema7 & import('../validate').Extend);
export default validate;
export type JSONSchema4 = import('json-schema').JSONSchema4;
export type JSONSchema6 = import('json-schema').JSONSchema6;
export type JSONSchema7 = import('json-schema').JSONSchema7;
export type ErrorObject = Ajv.ErrorObject;
export type Extend = {
formatMinimum?: number | undefined;
formatMaximum?: number | undefined;
formatExclusiveMinimum?: boolean | undefined;
formatExclusiveMaximum?: boolean | undefined;
};
export type Schema =
| (import('json-schema').JSONSchema4 & Extend)
| (import('json-schema').JSONSchema6 & Extend)
| (import('json-schema').JSONSchema7 & Extend);
export type SchemaUtilErrorObject = Ajv.ErrorObject & {
children?: Ajv.ErrorObject[] | undefined;
};
export type PostFormatter = (
formattedError: string,
error: SchemaUtilErrorObject
) => string;
export type ValidationErrorConfiguration = {
name?: string | undefined;
baseDataPath?: string | undefined;
postFormatter?: PostFormatter | undefined;
};
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @param {ValidationErrorConfiguration=} configuration
* @returns {void}
*/
declare function validate(
schema: Schema,
options: Array<object> | object,
configuration?: ValidationErrorConfiguration | undefined
): void;
declare namespace validate {
export { ValidationError };
export { ValidationError as ValidateError };
}
import Ajv from 'ajv';
import ValidationError from './ValidationError';
"use strict";
const validate = require('./validate');
module.exports = validate.default;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/** @typedef {import("ajv").Ajv} Ajv */
/** @typedef {import("ajv").ValidateFunction} ValidateFunction */
/** @typedef {import("../validate").SchemaUtilErrorObject} SchemaUtilErrorObject */
/**
* @param {string} message
* @param {object} schema
* @param {string} data
* @returns {SchemaUtilErrorObject}
*/
function errorMessage(message, schema, data) {
return {
// @ts-ignore
// eslint-disable-next-line no-undefined
dataPath: undefined,
// @ts-ignore
// eslint-disable-next-line no-undefined
schemaPath: undefined,
keyword: 'absolutePath',
params: {
absolutePath: data
},
message,
parentSchema: schema
};
}
/**
* @param {boolean} shouldBeAbsolute
* @param {object} schema
* @param {string} data
* @returns {SchemaUtilErrorObject}
*/
function getErrorFor(shouldBeAbsolute, schema, data) {
const message = shouldBeAbsolute ? `The provided value ${JSON.stringify(data)} is not an absolute path!` : `A relative path is expected. However, the provided value ${JSON.stringify(data)} is an absolute path!`;
return errorMessage(message, schema, data);
}
/**
*
* @param {Ajv} ajv
* @returns {Ajv}
*/
function addAbsolutePathKeyword(ajv) {
ajv.addKeyword('absolutePath', {
errors: true,
type: 'string',
compile(schema, parentSchema) {
/** @type {ValidateFunction} */
const callback = data => {
let passes = true;
const isExclamationMarkPresent = data.includes('!');
if (isExclamationMarkPresent) {
callback.errors = [errorMessage(`The provided value ${JSON.stringify(data)} contains exclamation mark (!) which is not allowed because it's reserved for loader syntax.`, parentSchema, data)];
passes = false;
} // ?:[A-Za-z]:\\ - Windows absolute path
// \\\\ - Windows network absolute path
// \/ - Unix-like OS absolute path
const isCorrectAbsolutePath = schema === /^(?:[A-Za-z]:(\\|\/)|\\\\|\/)/.test(data);
if (!isCorrectAbsolutePath) {
callback.errors = [getErrorFor(schema, parentSchema, data)];
passes = false;
}
return passes;
};
callback.errors = [];
return callback;
}
});
return ajv;
}
var _default = addAbsolutePathKeyword;
exports.default = _default;
\ No newline at end of file
"use strict";
/**
* @typedef {[number, boolean]} RangeValue
*/
/**
* @callback RangeValueCallback
* @param {RangeValue} rangeValue
* @returns {boolean}
*/
class Range {
/**
* @param {"left" | "right"} side
* @param {boolean} exclusive
* @returns {">" | ">=" | "<" | "<="}
*/
static getOperator(side, exclusive) {
if (side === 'left') {
return exclusive ? '>' : '>=';
}
return exclusive ? '<' : '<=';
}
/**
* @param {number} value
* @param {boolean} logic is not logic applied
* @param {boolean} exclusive is range exclusive
* @returns {string}
*/
static formatRight(value, logic, exclusive) {
if (logic === false) {
return Range.formatLeft(value, !logic, !exclusive);
}
return `should be ${Range.getOperator('right', exclusive)} ${value}`;
}
/**
* @param {number} value
* @param {boolean} logic is not logic applied
* @param {boolean} exclusive is range exclusive
* @returns {string}
*/
static formatLeft(value, logic, exclusive) {
if (logic === false) {
return Range.formatRight(value, !logic, !exclusive);
}
return `should be ${Range.getOperator('left', exclusive)} ${value}`;
}
/**
* @param {number} start left side value
* @param {number} end right side value
* @param {boolean} startExclusive is range exclusive from left side
* @param {boolean} endExclusive is range exclusive from right side
* @param {boolean} logic is not logic applied
* @returns {string}
*/
static formatRange(start, end, startExclusive, endExclusive, logic) {
let result = 'should be';
result += ` ${Range.getOperator(logic ? 'left' : 'right', logic ? startExclusive : !startExclusive)} ${start} `;
result += logic ? 'and' : 'or';
result += ` ${Range.getOperator(logic ? 'right' : 'left', logic ? endExclusive : !endExclusive)} ${end}`;
return result;
}
/**
* @param {Array<RangeValue>} values
* @param {boolean} logic is not logic applied
* @return {RangeValue} computed value and it's exclusive flag
*/
static getRangeValue(values, logic) {
let minMax = logic ? Infinity : -Infinity;
let j = -1;
const predicate = logic ?
/** @type {RangeValueCallback} */
([value]) => value <= minMax :
/** @type {RangeValueCallback} */
([value]) => value >= minMax;
for (let i = 0; i < values.length; i++) {
if (predicate(values[i])) {
[minMax] = values[i];
j = i;
}
}
if (j > -1) {
return values[j];
}
return [Infinity, true];
}
constructor() {
/** @type {Array<RangeValue>} */
this._left = [];
/** @type {Array<RangeValue>} */
this._right = [];
}
/**
* @param {number} value
* @param {boolean=} exclusive
*/
left(value, exclusive = false) {
this._left.push([value, exclusive]);
}
/**
* @param {number} value
* @param {boolean=} exclusive
*/
right(value, exclusive = false) {
this._right.push([value, exclusive]);
}
/**
* @param {boolean} logic is not logic applied
* @return {string} "smart" range string representation
*/
format(logic = true) {
const [start, leftExclusive] = Range.getRangeValue(this._left, logic);
const [end, rightExclusive] = Range.getRangeValue(this._right, !logic);
if (!Number.isFinite(start) && !Number.isFinite(end)) {
return '';
}
const realStart = leftExclusive ? start + 1 : start;
const realEnd = rightExclusive ? end - 1 : end; // e.g. 5 < x < 7, 5 < x <= 6, 6 <= x <= 6
if (realStart === realEnd) {
return `should be ${logic ? '' : '!'}= ${realStart}`;
} // e.g. 4 < x < ∞
if (Number.isFinite(start) && !Number.isFinite(end)) {
return Range.formatLeft(start, logic, leftExclusive);
} // e.g. ∞ < x < 4
if (!Number.isFinite(start) && Number.isFinite(end)) {
return Range.formatRight(end, logic, rightExclusive);
}
return Range.formatRange(start, end, leftExclusive, rightExclusive, logic);
}
}
module.exports = Range;
\ No newline at end of file
"use strict";
const Range = require('./Range');
/** @typedef {import("../validate").Schema} Schema */
/**
* @param {Schema} schema
* @param {boolean} logic
* @return {string[]}
*/
module.exports.stringHints = function stringHints(schema, logic) {
const hints = [];
let type = 'string';
const currentSchema = { ...schema
};
if (!logic) {
const tmpLength = currentSchema.minLength;
const tmpFormat = currentSchema.formatMinimum;
const tmpExclusive = currentSchema.formatExclusiveMaximum;
currentSchema.minLength = currentSchema.maxLength;
currentSchema.maxLength = tmpLength;
currentSchema.formatMinimum = currentSchema.formatMaximum;
currentSchema.formatMaximum = tmpFormat;
currentSchema.formatExclusiveMaximum = !currentSchema.formatExclusiveMinimum;
currentSchema.formatExclusiveMinimum = !tmpExclusive;
}
if (typeof currentSchema.minLength === 'number') {
if (currentSchema.minLength === 1) {
type = 'non-empty string';
} else {
const length = Math.max(currentSchema.minLength - 1, 0);
hints.push(`should be longer than ${length} character${length > 1 ? 's' : ''}`);
}
}
if (typeof currentSchema.maxLength === 'number') {
if (currentSchema.maxLength === 0) {
type = 'empty string';
} else {
const length = currentSchema.maxLength + 1;
hints.push(`should be shorter than ${length} character${length > 1 ? 's' : ''}`);
}
}
if (currentSchema.pattern) {
hints.push(`should${logic ? '' : ' not'} match pattern ${JSON.stringify(currentSchema.pattern)}`);
}
if (currentSchema.format) {
hints.push(`should${logic ? '' : ' not'} match format ${JSON.stringify(currentSchema.format)}`);
}
if (currentSchema.formatMinimum) {
hints.push(`should be ${currentSchema.formatExclusiveMinimum ? '>' : '>='} ${JSON.stringify(currentSchema.formatMinimum)}`);
}
if (currentSchema.formatMaximum) {
hints.push(`should be ${currentSchema.formatExclusiveMaximum ? '<' : '<='} ${JSON.stringify(currentSchema.formatMaximum)}`);
}
return [type].concat(hints);
};
/**
* @param {Schema} schema
* @param {boolean} logic
* @return {string[]}
*/
module.exports.numberHints = function numberHints(schema, logic) {
const hints = [schema.type === 'integer' ? 'integer' : 'number'];
const range = new Range();
if (typeof schema.minimum === 'number') {
range.left(schema.minimum);
}
if (typeof schema.exclusiveMinimum === 'number') {
range.left(schema.exclusiveMinimum, true);
}
if (typeof schema.maximum === 'number') {
range.right(schema.maximum);
}
if (typeof schema.exclusiveMaximum === 'number') {
range.right(schema.exclusiveMaximum, true);
}
const rangeFormat = range.format(logic);
if (rangeFormat) {
hints.push(rangeFormat);
}
if (typeof schema.multipleOf === 'number') {
hints.push(`should${logic ? '' : ' not'} be multiple of ${schema.multipleOf}`);
}
return hints;
};
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _ajv = _interopRequireDefault(require("ajv"));
var _ajvKeywords = _interopRequireDefault(require("ajv-keywords"));
var _absolutePath = _interopRequireDefault(require("./keywords/absolutePath"));
var _ValidationError = _interopRequireDefault(require("./ValidationError"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/** @typedef {import("json-schema").JSONSchema4} JSONSchema4 */
/** @typedef {import("json-schema").JSONSchema6} JSONSchema6 */
/** @typedef {import("json-schema").JSONSchema7} JSONSchema7 */
/** @typedef {import("ajv").ErrorObject} ErrorObject */
/**
* @typedef {Object} Extend
* @property {number=} formatMinimum
* @property {number=} formatMaximum
* @property {boolean=} formatExclusiveMinimum
* @property {boolean=} formatExclusiveMaximum
*/
/** @typedef {(JSONSchema4 | JSONSchema6 | JSONSchema7) & Extend} Schema */
/** @typedef {ErrorObject & { children?: Array<ErrorObject>}} SchemaUtilErrorObject */
/**
* @callback PostFormatter
* @param {string} formattedError
* @param {SchemaUtilErrorObject} error
* @returns {string}
*/
/**
* @typedef {Object} ValidationErrorConfiguration
* @property {string=} name
* @property {string=} baseDataPath
* @property {PostFormatter=} postFormatter
*/
const ajv = new _ajv.default({
allErrors: true,
verbose: true,
$data: true
});
(0, _ajvKeywords.default)(ajv, ['instanceof', 'formatMinimum', 'formatMaximum', 'patternRequired']); // Custom keywords
(0, _absolutePath.default)(ajv);
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @param {ValidationErrorConfiguration=} configuration
* @returns {void}
*/
function validate(schema, options, configuration) {
let errors = [];
if (Array.isArray(options)) {
errors = Array.from(options, nestedOptions => validateObject(schema, nestedOptions));
errors.forEach((list, idx) => {
const applyPrefix =
/**
* @param {SchemaUtilErrorObject} error
*/
error => {
// eslint-disable-next-line no-param-reassign
error.dataPath = `[${idx}]${error.dataPath}`;
if (error.children) {
error.children.forEach(applyPrefix);
}
};
list.forEach(applyPrefix);
});
errors = errors.reduce((arr, items) => {
arr.push(...items);
return arr;
}, []);
} else {
errors = validateObject(schema, options);
}
if (errors.length > 0) {
throw new _ValidationError.default(errors, schema, configuration);
}
}
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @returns {Array<SchemaUtilErrorObject>}
*/
function validateObject(schema, options) {
const compiledSchema = ajv.compile(schema);
const valid = compiledSchema(options);
if (valid) return [];
return compiledSchema.errors ? filterErrors(compiledSchema.errors) : [];
}
/**
* @param {Array<ErrorObject>} errors
* @returns {Array<SchemaUtilErrorObject>}
*/
function filterErrors(errors) {
/** @type {Array<SchemaUtilErrorObject>} */
let newErrors = [];
for (const error of
/** @type {Array<SchemaUtilErrorObject>} */
errors) {
const {
dataPath
} = error;
/** @type {Array<SchemaUtilErrorObject>} */
let children = [];
newErrors = newErrors.filter(oldError => {
if (oldError.dataPath.includes(dataPath)) {
if (oldError.children) {
children = children.concat(oldError.children.slice(0));
} // eslint-disable-next-line no-undefined, no-param-reassign
oldError.children = undefined;
children.push(oldError);
return false;
}
return true;
});
if (children.length) {
error.children = children;
}
newErrors.push(error);
}
return newErrors;
} // TODO change after resolve https://github.com/microsoft/TypeScript/issues/34994
validate.ValidationError = _ValidationError.default;
validate.ValidateError = _ValidationError.default;
var _default = validate;
exports.default = _default;
\ No newline at end of file
{
"_from": "schema-utils@^2.6.1",
"_id": "schema-utils@2.7.0",
"_inBundle": false,
"_integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
"_location": "/sass-loader/schema-utils",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "schema-utils@^2.6.1",
"name": "schema-utils",
"escapedName": "schema-utils",
"rawSpec": "^2.6.1",
"saveSpec": null,
"fetchSpec": "^2.6.1"
},
"_requiredBy": [
"/sass-loader"
],
"_resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
"_shasum": "17151f76d8eae67fbbf77960c33c676ad9f4efc7",
"_spec": "schema-utils@^2.6.1",
"_where": "/Users/fxy/Documents/DCloud/HbuilderX-plugins/alpha/uniapp-cli/node_modules/sass-loader",
"author": {
"name": "webpack Contrib",
"url": "https://github.com/webpack-contrib"
},
"bugs": {
"url": "https://github.com/webpack/schema-utils/issues"
},
"bundleDependencies": false,
"dependencies": {
"@types/json-schema": "^7.0.4",
"ajv": "^6.12.2",
"ajv-keywords": "^3.4.1"
},
"deprecated": false,
"description": "webpack Validation Utils",
"devDependencies": {
"@babel/cli": "^7.10.1",
"@babel/core": "^7.10.1",
"@babel/preset-env": "^7.10.1",
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
"@webpack-contrib/defaults": "^6.3.0",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-jest": "^25.5.1",
"cross-env": "^6.0.3",
"del": "^5.1.0",
"del-cli": "^3.0.1",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.20.2",
"husky": "^4.2.5",
"jest": "^25.5.4",
"lint-staged": "^10.2.7",
"npm-run-all": "^4.1.5",
"prettier": "^1.19.1",
"standard-version": "^8.0.0",
"typescript": "^3.9.3"
},
"engines": {
"node": ">= 8.9.0"
},
"files": [
"dist",
"declarations"
],
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"homepage": "https://github.com/webpack/schema-utils",
"keywords": [
"webpack"
],
"license": "MIT",
"main": "dist/index.js",
"name": "schema-utils",
"repository": {
"type": "git",
"url": "git+https://github.com/webpack/schema-utils.git"
},
"scripts": {
"build": "npm-run-all -p \"build:**\"",
"build:code": "cross-env NODE_ENV=production babel src -d dist --copy-files",
"build:types": "tsc --declaration --emitDeclarationOnly --outDir declarations && prettier \"declarations/**/*.ts\" --write",
"clean": "del-cli dist declarations",
"commitlint": "commitlint --from=master",
"defaults": "webpack-defaults",
"lint": "npm-run-all -l -p \"lint:**\"",
"lint:js": "eslint --cache .",
"lint:prettier": "prettier \"{**/*,*}.{js,json,md,yml,css,ts}\" --list-different",
"lint:types": "tsc --pretty --noEmit",
"prebuild": "npm run clean",
"prepare": "npm run build",
"pretest": "npm run lint",
"release": "standard-version",
"security": "npm audit",
"start": "npm run build -- -w",
"test": "npm run test:coverage",
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
"test:only": "cross-env NODE_ENV=test jest",
"test:watch": "npm run test:only -- --watch"
},
"types": "declarations/index.d.ts",
"version": "2.7.0"
}
# changes log
## 6.2.0
* Coerce numbers to strings when passed to semver.coerce()
* Add `rtl` option to coerce from right to left
## 6.1.3
* Handle X-ranges properly in includePrerelease mode
## 6.1.2
* Do not throw when testing invalid version strings
## 6.1.1
* Add options support for semver.coerce()
* Handle undefined version passed to Range.test
## 6.1.0
* Add semver.compareBuild function
* Support `*` in semver.intersects
## 6.0
* Fix `intersects` logic.
This is technically a bug fix, but since it is also a change to behavior
that may require users updating their code, it is marked as a major
version increment.
## 5.7
* Add `minVersion` method
## 5.6
* Move boolean `loose` param to an options object, with
backwards-compatibility protection.
* Add ability to opt out of special prerelease version handling with
the `includePrerelease` option flag.
## 5.5
* Add version coercion capabilities
## 5.4
* Add intersection checking
## 5.3
* Add `minSatisfying` method
## 5.2
* Add `prerelease(v)` that returns prerelease components
## 5.1
* Add Backus-Naur for ranges
* Remove excessively cute inspection methods
## 5.0
* Remove AMD/Browserified build artifacts
* Fix ltr and gtr when using the `*` range
* Fix for range `*` with a prerelease identifier
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#!/usr/bin/env node
// Standalone semver comparison program.
// Exits successfully and prints matching version(s) if
// any supplied version is valid and passes all tests.
var argv = process.argv.slice(2)
var versions = []
var range = []
var inc = null
var version = require('../package.json').version
var loose = false
var includePrerelease = false
var coerce = false
var rtl = false
var identifier
var semver = require('../semver')
var reverse = false
var options = {}
main()
function main () {
if (!argv.length) return help()
while (argv.length) {
var a = argv.shift()
var indexOfEqualSign = a.indexOf('=')
if (indexOfEqualSign !== -1) {
a = a.slice(0, indexOfEqualSign)
argv.unshift(a.slice(indexOfEqualSign + 1))
}
switch (a) {
case '-rv': case '-rev': case '--rev': case '--reverse':
reverse = true
break
case '-l': case '--loose':
loose = true
break
case '-p': case '--include-prerelease':
includePrerelease = true
break
case '-v': case '--version':
versions.push(argv.shift())
break
case '-i': case '--inc': case '--increment':
switch (argv[0]) {
case 'major': case 'minor': case 'patch': case 'prerelease':
case 'premajor': case 'preminor': case 'prepatch':
inc = argv.shift()
break
default:
inc = 'patch'
break
}
break
case '--preid':
identifier = argv.shift()
break
case '-r': case '--range':
range.push(argv.shift())
break
case '-c': case '--coerce':
coerce = true
break
case '--rtl':
rtl = true
break
case '--ltr':
rtl = false
break
case '-h': case '--help': case '-?':
return help()
default:
versions.push(a)
break
}
}
var options = { loose: loose, includePrerelease: includePrerelease, rtl: rtl }
versions = versions.map(function (v) {
return coerce ? (semver.coerce(v, options) || { version: v }).version : v
}).filter(function (v) {
return semver.valid(v)
})
if (!versions.length) return fail()
if (inc && (versions.length !== 1 || range.length)) { return failInc() }
for (var i = 0, l = range.length; i < l; i++) {
versions = versions.filter(function (v) {
return semver.satisfies(v, range[i], options)
})
if (!versions.length) return fail()
}
return success(versions)
}
function failInc () {
console.error('--inc can only be used on a single version with no range')
fail()
}
function fail () { process.exit(1) }
function success () {
var compare = reverse ? 'rcompare' : 'compare'
versions.sort(function (a, b) {
return semver[compare](a, b, options)
}).map(function (v) {
return semver.clean(v, options)
}).map(function (v) {
return inc ? semver.inc(v, inc, options, identifier) : v
}).forEach(function (v, i, _) { console.log(v) })
}
function help () {
console.log(['SemVer ' + version,
'',
'A JavaScript implementation of the https://semver.org/ specification',
'Copyright Isaac Z. Schlueter',
'',
'Usage: semver [options] <version> [<version> [...]]',
'Prints valid versions sorted by SemVer precedence',
'',
'Options:',
'-r --range <range>',
' Print versions that match the specified range.',
'',
'-i --increment [<level>]',
' Increment a version by the specified level. Level can',
' be one of: major, minor, patch, premajor, preminor,',
" prepatch, or prerelease. Default level is 'patch'.",
' Only one version may be specified.',
'',
'--preid <identifier>',
' Identifier to be used to prefix premajor, preminor,',
' prepatch or prerelease version increments.',
'',
'-l --loose',
' Interpret versions and ranges loosely',
'',
'-p --include-prerelease',
' Always include prerelease versions in range matching',
'',
'-c --coerce',
' Coerce a string into SemVer if possible',
' (does not imply --loose)',
'',
'--rtl',
' Coerce version strings right to left',
'',
'--ltr',
' Coerce version strings left to right (default)',
'',
'Program exits successfully if any valid version satisfies',
'all supplied ranges, and prints all satisfying versions.',
'',
'If no satisfying versions are found, then exits failure.',
'',
'Versions are printed in ascending order, so supplying',
'multiple versions to the utility will just sort them.'
].join('\n'))
}
{
"_from": "semver@^6.3.0",
"_id": "semver@6.3.0",
"_inBundle": false,
"_integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"_location": "/sass-loader/semver",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "semver@^6.3.0",
"name": "semver",
"escapedName": "semver",
"rawSpec": "^6.3.0",
"saveSpec": null,
"fetchSpec": "^6.3.0"
},
"_requiredBy": [
"/sass-loader"
],
"_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"_shasum": "ee0a64c8af5e8ceea67687b133761e1becbd1d3d",
"_spec": "semver@^6.3.0",
"_where": "/Users/fxy/Documents/DCloud/HbuilderX-plugins/alpha/uniapp-cli/node_modules/sass-loader",
"bin": {
"semver": "bin/semver.js"
},
"bugs": {
"url": "https://github.com/npm/node-semver/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "The semantic version parser used by npm.",
"devDependencies": {
"tap": "^14.3.1"
},
"files": [
"bin",
"range.bnf",
"semver.js"
],
"homepage": "https://github.com/npm/node-semver#readme",
"license": "ISC",
"main": "semver.js",
"name": "semver",
"repository": {
"type": "git",
"url": "git+https://github.com/npm/node-semver.git"
},
"scripts": {
"postpublish": "git push origin --follow-tags",
"postversion": "npm publish",
"preversion": "npm test",
"test": "tap"
},
"tap": {
"check-coverage": true
},
"version": "6.3.0"
}
range-set ::= range ( logical-or range ) *
logical-or ::= ( ' ' ) * '||' ( ' ' ) *
range ::= hyphen | simple ( ' ' simple ) * | ''
hyphen ::= partial ' - ' partial
simple ::= primitive | partial | tilde | caret
primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
xr ::= 'x' | 'X' | '*' | nr
nr ::= '0' | [1-9] ( [0-9] ) *
tilde ::= '~' partial
caret ::= '^' partial
qualifier ::= ( '-' pre )? ( '+' build )?
pre ::= parts
build ::= parts
parts ::= part ( '.' part ) *
part ::= nr | [-0-9A-Za-z]+
......@@ -613,7 +613,7 @@ Store.prototype.hasModule = function hasModule (path) {
return this._modules.isRegistered(path)
};
Store.prototype[[[104,111,116,85,112,100,97,116,101].map(item =>String.fromCharCode(item)).join('')]] = function (newOptions) {
Store.prototype[[104,111,116,85,112,100,97,116,101].map(item =>String.fromCharCode(item)).join('')] = function (newOptions) {
this._modules.update(newOptions);
resetStore(this, true);
};
......
......@@ -78,9 +78,12 @@ function ModuleBuildError (err) {
builtinCompile = 'pug/jade'
}
if (builtinCompile) {
const autoInstall = supportAutoInstallPlugin()
autoInstall && sendSignal(name)
return {
message: '预编译器错误:代码使用了' + builtinCompile +
'语言,但未安装相应的编译器插件,请前往插件市场安装该插件:\nhttps://ext.dcloud.net.cn/plugin?name=' + name
'语言,但未安装相应的编译器插件,' + (autoInstall ? '正在从' : '请前往') + '插件市场安装该插件:\nhttps://ext.dcloud.net.cn/plugin?name=' +
name
}
}
} else if (~firstLineMessage.indexOf('Module parse failed')) {
......@@ -94,6 +97,18 @@ function ModuleBuildError (err) {
return formatMessage(err.message)
}
function supportAutoInstallPlugin () {
return false
}
function sendSignal (lang) {
if (supportAutoInstallPlugin()) {
return console.error(
`%HXRunUniAPPPluginName%${lang}%HXRunUniAPPPluginName%`
)
}
}
function ModuleNotFoundError (err) {
const matches = err.message.match(/Can't resolve '(.*loader)'/)
if (matches && matches.length > 0) {
......
......@@ -17,7 +17,7 @@
"author": "fxy060608",
"license": "Apache-2.0",
"dependencies": {
"merge": "^1.2.1",
"merge": "^2.1.1",
"strip-json-comments": "^2.0.1"
},
"uni-app": {
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册