Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

vue-loader

Package Overview
Dependencies
Maintainers
2
Versions
304
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vue-loader - npm Package Compare versions

Comparing version 15.9.8 to 15.10.0-beta.1

lib/compiler.js

21

CHANGELOG.md

@@ -0,1 +1,12 @@

<a name="15.10.0-beta.1"></a>
# [15.10.0-beta.1](https://github.com/vuejs/vue-loader/compare/v15.9.8...v15.10.0-beta.1) (2022-06-14)
### Features
* apply js loaders to compiled template code when used with 2.7 ([30464a8](https://github.com/vuejs/vue-loader/commit/30464a8))
* compat for vue 2.7, support `<script setup>` ([308715a](https://github.com/vuejs/vue-loader/commit/308715a))
<a name="15.9.8"></a>

@@ -11,2 +22,12 @@ ## [15.9.8](https://github.com/vuejs/vue-loader/compare/v15.9.7...v15.9.8) (2021-08-02)

<a name="15.9.8"></a>
## [15.9.8](https://github.com/vuejs/vue-loader/compare/v15.9.7...v15.9.8) (2021-08-02)
### Bug Fixes
* fix webpack 5.48 compatibility ([c4c5f17](https://github.com/vuejs/vue-loader/commit/c4c5f17)), closes [#1859](https://github.com/vuejs/vue-loader/issues/1859)
<a name="15.9.7"></a>

@@ -13,0 +34,0 @@ ## [15.9.7](https://github.com/vuejs/vue-loader/compare/v15.9.6...v15.9.7) (2021-05-11)

89

lib/index.js

@@ -8,3 +8,2 @@ const path = require('path')

const { attrsToQuery } = require('./codegen/utils')
const { parse } = require('@vue/component-compiler-utils')
const genStylesCode = require('./codegen/styleInjection')

@@ -15,20 +14,6 @@ const { genHotReloadCode } = require('./codegen/hotReload')

const { NS } = require('./plugin')
const { resolveCompiler } = require('./compiler')
let errorEmitted = false
function loadTemplateCompiler (loaderContext) {
try {
return require('vue-template-compiler')
} catch (e) {
if (/version mismatch/.test(e.toString())) {
loaderContext.emitError(e)
} else {
loaderContext.emitError(new Error(
`[vue-loader] vue-template-compiler must be installed as a peer dependency, ` +
`or a compatible compiler implementation must be passed via options.`
))
}
}
}
module.exports = function (source) {

@@ -38,6 +23,8 @@ const loaderContext = this

if (!errorEmitted && !loaderContext['thread-loader'] && !loaderContext[NS]) {
loaderContext.emitError(new Error(
`vue-loader was used without the corresponding plugin. ` +
`Make sure to include VueLoaderPlugin in your webpack config.`
))
loaderContext.emitError(
new Error(
`vue-loader was used without the corresponding plugin. ` +
`Make sure to include VueLoaderPlugin in your webpack config.`
)
)
errorEmitted = true

@@ -65,3 +52,4 @@ }

const isShadow = !!options.shadowMode
const isProduction = options.productionMode || minimize || process.env.NODE_ENV === 'production'
const isProduction =
options.productionMode || minimize || process.env.NODE_ENV === 'production'
const filename = path.basename(resourcePath)

@@ -71,5 +59,10 @@ const context = rootContext || process.cwd()

const descriptor = parse({
const { compiler, templateCompiler } = resolveCompiler(
rootContext,
loaderContext
)
const descriptor = compiler.parse({
source,
compiler: options.compiler || loadTemplateCompiler(loaderContext),
compiler: options.compiler || templateCompiler,
filename,

@@ -86,2 +79,3 @@ sourceRoot,

descriptor,
options,
loaderContext,

@@ -102,3 +96,3 @@ incomingQuery,

isProduction
? (shortFilePath + '\n' + source.replace(/\r\n/g, '\n'))
? shortFilePath + '\n' + source.replace(/\r\n/g, '\n')
: shortFilePath

@@ -109,10 +103,25 @@ )

const hasScoped = descriptor.styles.some(s => s.scoped)
const hasFunctional = descriptor.template && descriptor.template.attrs.functional
const needsHotReload = (
const hasFunctional =
descriptor.template && descriptor.template.attrs.functional
const needsHotReload =
!isServer &&
!isProduction &&
(descriptor.script || descriptor.template) &&
(descriptor.script || descriptor.scriptSetup || descriptor.template) &&
options.hotReload !== false
)
// script
let scriptImport = `var script = {}`
// let isTS = false
const { script, scriptSetup } = descriptor
if (script || scriptSetup) {
// const lang = script?.lang || scriptSetup?.lang
// isTS = !!(lang && /tsx?/.test(lang))
const src = (script && !scriptSetup && script.src) || resourcePath
const attrsQuery = attrsToQuery((scriptSetup || script).attrs, 'js')
const query = `?vue&type=script${attrsQuery}${inheritQuery}`
const request = stringifyRequest(src + query)
scriptImport =
`import script from ${request}\n` + `export * from ${request}` // support named exports
}
// template

@@ -126,20 +135,9 @@ let templateImport = `var render, staticRenderFns`

const attrsQuery = attrsToQuery(descriptor.template.attrs)
// const tsQuery =
// options.enableTsInTemplate !== false && isTS ? `&ts=true` : ``
const query = `?vue&type=template${idQuery}${scopedQuery}${attrsQuery}${inheritQuery}`
const request = templateRequest = stringifyRequest(src + query)
const request = (templateRequest = stringifyRequest(src + query))
templateImport = `import { render, staticRenderFns } from ${request}`
}
// script
let scriptImport = `var script = {}`
if (descriptor.script) {
const src = descriptor.script.src || resourcePath
const attrsQuery = attrsToQuery(descriptor.script.attrs, 'js')
const query = `?vue&type=script${attrsQuery}${inheritQuery}`
const request = stringifyRequest(src + query)
scriptImport = (
`import script from ${request}\n` +
`export * from ${request}` // support named exports
)
}
// styles

@@ -159,3 +157,4 @@ let stylesCode = ``

let code = `
let code =
`
${templateImport}

@@ -196,3 +195,5 @@ ${scriptImport}

// from the devtools.
code += `\ncomponent.options.__file = ${JSON.stringify(rawShortFilePath.replace(/\\/g, '/'))}`
code += `\ncomponent.options.__file = ${JSON.stringify(
rawShortFilePath.replace(/\\/g, '/')
)}`
} else if (options.exposeFilename) {

@@ -199,0 +200,0 @@ // Libraries can opt-in to expose their components' filenames in production builds.

@@ -7,2 +7,3 @@ const qs = require('querystring')

const stylePostLoaderPath = require.resolve('./stylePostLoader')
const { resolveCompiler } = require('../compiler')

@@ -94,5 +95,4 @@ const isESLintLoader = l => /(\/|\\|@)eslint-loader/.test(l.path)

loaders.forEach(loader => {
const identifier = typeof loader === 'string'
? loader
: (loader.path + loader.query)
const identifier =
typeof loader === 'string' ? loader : loader.path + loader.query
const request = typeof loader === 'string' ? loader : loader.request

@@ -107,6 +107,7 @@ if (!seen.has(identifier)) {

return loaderUtils.stringifyRequest(this, '-!' + [
...loaderStrings,
this.resourcePath + this.resourceQuery
].join('!'))
return loaderUtils.stringifyRequest(
this,
'-!' +
[...loaderStrings, this.resourcePath + this.resourceQuery].join('!')
)
}

@@ -135,16 +136,21 @@

const path = require('path')
const cacheLoader = cacheDirectory && cacheIdentifier
? [`${require.resolve('cache-loader')}?${JSON.stringify({
// For some reason, webpack fails to generate consistent hash if we
// use absolute paths here, even though the path is only used in a
// comment. For now we have to ensure cacheDirectory is a relative path.
cacheDirectory: (path.isAbsolute(cacheDirectory)
? path.relative(process.cwd(), cacheDirectory)
: cacheDirectory).replace(/\\/g, '/'),
cacheIdentifier: hash(cacheIdentifier) + '-vue-loader-template'
})}`]
: []
const cacheLoader =
cacheDirectory && cacheIdentifier
? [
`${require.resolve('cache-loader')}?${JSON.stringify({
// For some reason, webpack fails to generate consistent hash if we
// use absolute paths here, even though the path is only used in a
// comment. For now we have to ensure cacheDirectory is a relative path.
cacheDirectory: (path.isAbsolute(cacheDirectory)
? path.relative(process.cwd(), cacheDirectory)
: cacheDirectory
).replace(/\\/g, '/'),
cacheIdentifier: hash(cacheIdentifier) + '-vue-loader-template'
})}`
]
: []
const preLoaders = loaders.filter(isPreLoader)
const postLoaders = loaders.filter(isPostLoader)
const { is27 } = resolveCompiler(this.rootContext, this)

@@ -154,6 +160,6 @@ const request = genRequest([

...postLoaders,
templateLoaderPath + `??vue-loader-options`,
...(is27 ? [] : [templateLoaderPath + `??vue-loader-options`]),
...preLoaders
])
// console.log(request)
// the template compiler uses esm exports

@@ -160,0 +166,0 @@ return `export * from ${request}`

const qs = require('querystring')
const { compileStyle } = require('@vue/component-compiler-utils')
const { resolveCompiler } = require('../compiler')

@@ -9,3 +9,4 @@ // This is a post loader that handles scoped CSS transforms.

const query = qs.parse(this.resourceQuery.slice(1))
const { code, map, errors } = compileStyle({
const { compiler } = resolveCompiler(this.rootContext, this)
const { code, map, errors } = compiler.compileStyle({
source,

@@ -12,0 +13,0 @@ filename: this.resourcePath,

const qs = require('querystring')
const loaderUtils = require('loader-utils')
const { compileTemplate } = require('@vue/component-compiler-utils')
const { resolveCompiler } = require('../compiler')

@@ -18,20 +18,29 @@ // Loader that compiles raw template into JavaScript functions.

const isServer = loaderContext.target === 'node'
const isProduction = options.productionMode || loaderContext.minimize || process.env.NODE_ENV === 'production'
const isProduction =
options.productionMode ||
loaderContext.minimize ||
process.env.NODE_ENV === 'production'
const isFunctional = query.functional
// allow using custom compiler via options
const compiler = options.compiler || require('vue-template-compiler')
const compilerOptions = Object.assign(
{
outputSourceRange: true
},
options.compilerOptions,
{
scopeId: query.scoped ? `data-v-${id}` : null,
comments: query.comments
}
)
const compilerOptions = Object.assign({
outputSourceRange: true
}, options.compilerOptions, {
scopeId: query.scoped ? `data-v-${id}` : null,
comments: query.comments
})
const { compiler, templateCompiler } = resolveCompiler(
loaderContext.rootContext,
loaderContext
)
// for vue-component-compiler
// for vue/compiler-sfc OR @vue/component-compiler-utils
const finalOptions = {
source,
filename: this.resourcePath,
compiler,
compiler: options.compiler || templateCompiler,
compilerOptions,

@@ -47,3 +56,3 @@ // allow customizing behavior of vue-template-es2015-compiler

const compiled = compileTemplate(finalOptions)
const compiled = compiler.compileTemplate(finalOptions)

@@ -59,4 +68,7 @@ // tips

if (compiled.errors && compiled.errors.length) {
const generateCodeFrame =
(templateCompiler && templateCompiler.generateCodeFrame) ||
compiler.generateCodeFrame
// 2.6 compiler outputs errors as objects with range
if (compiler.generateCodeFrame && finalOptions.compilerOptions.outputSourceRange) {
if (generateCodeFrame && finalOptions.compilerOptions.outputSourceRange) {
// TODO account for line offset in case template isn't placed at top

@@ -66,7 +78,9 @@ // of the file

`\n\n Errors compiling template:\n\n` +
compiled.errors.map(({ msg, start, end }) => {
const frame = compiler.generateCodeFrame(source, start, end)
return ` ${msg}\n\n${pad(frame)}`
}).join(`\n\n`) +
'\n'
compiled.errors
.map(({ msg, start, end }) => {
const frame = generateCodeFrame(source, start, end)
return ` ${msg}\n\n${pad(frame)}`
})
.join(`\n\n`) +
'\n'
)

@@ -73,0 +87,0 @@ } else {

const qs = require('querystring')
const RuleSet = require('webpack/lib/RuleSet')
const { resolveCompiler } = require('./compiler')

@@ -41,3 +42,3 @@ const id = 'vue-loader-plugin'

`[VueLoaderPlugin Error] No matching rule for .vue files found.\n` +
`Make sure there is at least one root-level rule that matches .vue or .vue.html files.`
`Make sure there is at least one root-level rule that matches .vue or .vue.html files.`
)

@@ -52,3 +53,3 @@ }

// get the normlized "use" for vue files
// get the normalized "use" for vue files
const vueUse = vueRule.use

@@ -63,3 +64,3 @@ // get vue-loader options

`[VueLoaderPlugin Error] No matching use for vue-loader is found.\n` +
`Make sure the rule matching .vue files include vue-loader in its use.`
`Make sure the rule matching .vue files include vue-loader in its use.`
)

@@ -75,8 +76,30 @@ }

// for each user rule (expect the vue rule), create a cloned rule
// for each user rule (except the vue rule), create a cloned rule
// that targets the corresponding language blocks in *.vue files.
const clonedRules = rules
.filter(r => r !== vueRule)
.map(cloneRule)
const clonedRules = rules.filter(r => r !== vueRule).map(cloneRule)
// rule for template compiler
const templateCompilerRule = {
loader: require.resolve('./loaders/templateLoader'),
resourceQuery: query => {
const parsed = qs.parse(query.slice(1))
return parsed.vue != null && parsed.type === 'template'
},
options: vueLoaderUse.options
}
// for each rule that matches plain .js/.ts files, also create a clone and
// match it against the compiled template code inside *.vue files, so that
// compiled vue render functions receive the same treatment as user code
// (mostly babel)
const { is27 } = resolveCompiler(compiler.options.context)
let jsRulesForRenderFn = []
if (is27) {
const matchesJS = createMatcher(`test.js`)
// const matchesTS = createMatcher(`test.ts`)
jsRulesForRenderFn = rules
.filter(r => r !== vueRule && matchesJS(r))
.map(cloneRuleForRenderFn)
}
// global pitcher (responsible for injecting template compiler loader & CSS

@@ -99,2 +122,4 @@ // post loader)

pitcher,
...jsRulesForRenderFn,
...(is27 ? [templateCompilerRule] : []),
...clonedRules,

@@ -112,7 +137,3 @@ ...rules

const normalized = RuleSet.normalizeRule(clone, {}, '')
return (
!rule.enforce &&
normalized.resource &&
normalized.resource(fakeFile)
)
return !rule.enforce && normalized.resource && normalized.resource(fakeFile)
}

@@ -166,3 +187,40 @@ }

function cloneRuleForRenderFn (rule) {
const resource = rule.resource
const resourceQuery = rule.resourceQuery
let currentResource
const res = {
...rule,
resource: resource => {
currentResource = resource
return true
},
resourceQuery: query => {
const parsed = qs.parse(query.slice(1))
if (parsed.vue == null || parsed.type !== 'template') {
return false
}
const fakeResourcePath = `${currentResource}.${parsed.ts ? `ts` : `js`}`
if (resource && !resource(fakeResourcePath)) {
return false
}
if (resourceQuery && !resourceQuery(query)) {
return false
}
return true
}
}
if (rule.rules) {
res.rules = rule.rules.map(cloneRuleForRenderFn)
}
if (rule.oneOf) {
res.oneOf = rule.oneOf.map(cloneRuleForRenderFn)
}
return res
}
VueLoaderPlugin.NS = NS
module.exports = VueLoaderPlugin

@@ -0,1 +1,3 @@

const { resolveCompiler } = require('./compiler')
const qs = require('querystring')

@@ -50,3 +52,4 @@ const id = 'vue-loader-plugin'

compiler.hooks.compilation.tap(id, compilation => {
const normalModuleLoader = normalModule.getCompilationHooks(compilation).loader
const normalModuleLoader = normalModule.getCompilationHooks(compilation)
.loader
normalModuleLoader.tap(id, loaderContext => {

@@ -58,3 +61,3 @@ loaderContext[NS] = true

const rules = compiler.options.module.rules
let rawVueRules
let rawVueRule
let vueRules = []

@@ -67,17 +70,5 @@

}
// skip the `include` check when locating the vue rule
const clonedRawRule = Object.assign({}, rawRule)
delete clonedRawRule.include
const ruleSet = ruleSetCompiler.compile([{
rules: [clonedRawRule]
}])
vueRules = ruleSet.exec({
resource: 'foo.vue'
})
vueRules = match(rawRule, 'foo.vue')
if (!vueRules.length) {
vueRules = ruleSet.exec({
resource: 'foo.vue.html'
})
vueRules = match(rawRule, 'foo.vue.html')
}

@@ -90,3 +81,3 @@ if (vueRules.length > 0) {

}
rawVueRules = rawRule
rawVueRule = rawRule
break

@@ -98,8 +89,10 @@ }

`[VueLoaderPlugin Error] No matching rule for .vue files found.\n` +
`Make sure there is at least one root-level rule that matches .vue or .vue.html files.`
`Make sure there is at least one root-level rule that matches .vue or .vue.html files.`
)
}
// get the normlized "use" for vue files
const vueUse = vueRules.filter(rule => rule.type === 'use').map(rule => rule.value)
// get the normalized "use" for vue files
const vueUse = vueRules
.filter(rule => rule.type === 'use')
.map(rule => rule.value)

@@ -114,3 +107,3 @@ // get vue-loader options

`[VueLoaderPlugin Error] No matching use for vue-loader is found.\n` +
`Make sure the rule matching .vue files include vue-loader in its use.`
`Make sure the rule matching .vue files include vue-loader in its use.`
)

@@ -130,10 +123,41 @@ }

const clonedRules = rules
.filter(r => r !== rawVueRules)
.map((rawRule) => cloneRule(rawRule, refs))
.filter(r => r !== rawVueRule)
.map(rawRule =>
cloneRule(rawRule, refs, langBlockRuleCheck, langBlockRuleResource)
)
// fix conflict with config.loader and config.options when using config.use
delete rawVueRules.loader
delete rawVueRules.options
rawVueRules.use = vueUse
delete rawVueRule.loader
delete rawVueRule.options
rawVueRule.use = vueUse
// rule for template compiler
const templateCompilerRule = {
loader: require.resolve('./loaders/templateLoader'),
resourceQuery: query => {
if (!query) {
return false
}
const parsed = qs.parse(query.slice(1))
return parsed.vue != null && parsed.type === 'template'
},
options: vueLoaderUse.options
}
// for each rule that matches plain .js files, also create a clone and
// match it against the compiled template code inside *.vue files, so that
// compiled vue render functions receive the same treatment as user code
// (mostly babel)
const { is27 } = resolveCompiler(compiler.options.context)
let jsRulesForRenderFn = []
if (is27) {
jsRulesForRenderFn = rules
.filter(
r =>
r !== rawVueRule &&
(match(r, 'test.js').length > 0 || match(r, 'test.ts').length > 0)
)
.map(rawRule => cloneRule(rawRule, refs, jsRuleCheck, jsRuleResource))
}
// global pitcher (responsible for injecting template compiler loader & CSS

@@ -144,3 +168,5 @@ // post loader)

resourceQuery: query => {
if (!query) { return false }
if (!query) {
return false
}
const parsed = qs.parse(query.slice(1))

@@ -158,2 +184,4 @@ return parsed.vue != null

pitcher,
...jsRulesForRenderFn,
...(is27 ? [templateCompilerRule] : []),
...clonedRules,

@@ -165,24 +193,49 @@ ...rules

const matcherCache = new WeakMap()
function match (rule, fakeFile) {
let ruleSet = matcherCache.get(rule)
if (!ruleSet) {
// skip the `include` check when locating the vue rule
const clonedRawRule = { ...rule }
delete clonedRawRule.include
ruleSet = ruleSetCompiler.compile([clonedRawRule])
matcherCache.set(rule, ruleSet)
}
return ruleSet.exec({
resource: fakeFile
})
}
const langBlockRuleCheck = (query, rule) => {
return (
query.type === 'custom' || !rule.conditions.length || query.lang != null
)
}
const langBlockRuleResource = (query, resource) => `${resource}.${query.lang}`
const jsRuleCheck = query => {
return query.type === 'template'
}
const jsRuleResource = (query, resource) =>
`${resource}.${query.ts ? `ts` : `js`}`
let uid = 0
function cloneRule (rawRule, refs) {
const rules = ruleSetCompiler.compileRules(`clonedRuleSet-${++uid}`, [{
rules: [rawRule]
}], refs)
let currentResource
const conditions = rules[0].rules
.map(rule => rule.conditions)
// shallow flat
.reduce((prev, next) => prev.concat(next), [])
function cloneRule (rawRule, refs, ruleCheck, ruleResource) {
const compiledRule = ruleSetCompiler.compileRule(
`clonedRuleSet-${++uid}`,
rawRule,
refs
)
// do not process rule with enforce
if (!rawRule.enforce) {
const ruleUse = rules[0].rules
.map(rule => rule.effects
.filter(effect => effect.type === 'use')
.map(effect => effect.value)
)
// shallow flat
.reduce((prev, next) => prev.concat(next), [])
const ruleUse = compiledRule.effects
.filter(effect => effect.type === 'use')
.map(effect => effect.value)
// fix conflict with config.loader and config.options when using config.use

@@ -194,3 +247,5 @@ delete rawRule.loader

const res = Object.assign({}, rawRule, {
let currentResource
const res = {
...rawRule,
resource: resources => {

@@ -201,3 +256,6 @@ currentResource = resources

resourceQuery: query => {
if (!query) { return false }
if (!query) {
return false
}
const parsed = qs.parse(query.slice(1))

@@ -207,9 +265,10 @@ if (parsed.vue == null) {

}
if (!conditions) {
if (!ruleCheck(parsed, compiledRule)) {
return false
}
const fakeResourcePath = `${currentResource}.${parsed.lang}`
for (const condition of conditions) {
const fakeResourcePath = ruleResource(parsed, currentResource)
for (const condition of compiledRule.conditions) {
// add support for resourceQuery
const request = condition.property === 'resourceQuery' ? query : fakeResourcePath
const request =
condition.property === 'resourceQuery' ? query : fakeResourcePath
if (condition && !condition.fn(request)) {

@@ -221,3 +280,3 @@ return false

}
})
}

@@ -227,7 +286,11 @@ delete res.test

if (rawRule.rules) {
res.rules = rawRule.rules.map(rule => cloneRule(rule, refs))
res.rules = rawRule.rules.map(rule =>
cloneRule(rule, refs, ruleCheck, ruleResource)
)
}
if (rawRule.oneOf) {
res.oneOf = rawRule.oneOf.map(rule => cloneRule(rule, refs))
res.oneOf = rawRule.oneOf.map(rule =>
cloneRule(rule, refs, ruleCheck, ruleResource)
)
}

@@ -234,0 +297,0 @@

@@ -0,3 +1,6 @@

const { resolveScript } = require('./resolveScript')
module.exports = function selectBlock (
descriptor,
options,
loaderContext,

@@ -22,10 +25,7 @@ query,

if (query.type === `script`) {
const script = resolveScript(descriptor, options, loaderContext)
if (appendExtension) {
loaderContext.resourcePath += '.' + (descriptor.script.lang || 'js')
loaderContext.resourcePath += '.' + (script.lang || 'js')
}
loaderContext.callback(
null,
descriptor.script.content,
descriptor.script.map
)
loaderContext.callback(null, script.content, script.map)
return

@@ -40,7 +40,3 @@ }

}
loaderContext.callback(
null,
style.content,
style.map
)
loaderContext.callback(null, style.content, style.map)
return

@@ -52,9 +48,5 @@ }

const block = descriptor.customBlocks[query.index]
loaderContext.callback(
null,
block.content,
block.map
)
loaderContext.callback(null, block.content, block.map)
return
}
}
{
"name": "vue-loader",
"version": "15.9.8",
"version": "15.10.0-beta.1",
"description": "Vue single-file component loader for Webpack",

@@ -78,3 +78,2 @@ "main": "lib/index.js",

"mini-css-extract-plugin": "^0.4.1",
"node-sass": "^4.7.2",
"normalize-newline": "^3.0.0",

@@ -86,3 +85,2 @@ "null-loader": "^0.1.1",

"raw-loader": "^0.5.1",
"sass-loader": "^6.0.7",
"source-map": "^0.5.0",

@@ -100,3 +98,3 @@ "stylus": "^0.54.5",

"vuepress-theme-vue": "^1.1.0",
"webpack": "^4.1.0",
"webpack": "^4.46.0",
"webpack-cli": "^3.2.0",

@@ -103,0 +101,0 @@ "webpack-dev-server": "^3.1.1",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc