Skip to content

Commit

Permalink
fix(dynamic-import-chunkname): Add proper webpack comment parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
st-sloth committed Aug 22, 2018
1 parent f7bd328 commit 8d8c20a
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 21 deletions.
19 changes: 19 additions & 0 deletions docs/rules/dynamic-import-chunkname.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ import(
/*webpackChunkName:"someModule"*/
'someModule',
);
import(
/* webpackChunkName : "someModule" */
'someModule',
);

// chunkname contains a 6 (forbidden by rule config)
import(
Expand All @@ -41,6 +45,12 @@ import(
'someModule',
);

// invalid syntax for webpack comment
import(
/* totally not webpackChunkName: "someModule" */
'someModule',
);

// single-line comment, not a block-style comment
import(
// webpackChunkName: "someModule"
Expand All @@ -59,6 +69,15 @@ The following patterns are valid:
/* webpackChunkName: "someOtherModule12345789" */
'someModule',
);
import(
/* webpackChunkName: "someModule" */
/* webpackPrefetch: true */
'someModule',
);
import(
/* webpackChunkName: "someModule", webpackPrefetch: true */
'someModule',
);
```

## When Not To Use It
Expand Down
65 changes: 52 additions & 13 deletions src/rules/dynamic-import-chunkname.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import vm from 'vm'
import docsUrl from '../docsUrl'

module.exports = {
Expand Down Expand Up @@ -27,8 +28,10 @@ module.exports = {
const { importFunctions = [] } = config || {}
const { webpackChunknameFormat = '[0-9a-zA-Z-_/.]+' } = config || {}

const commentFormat = ` webpackChunkName: "${webpackChunknameFormat}" `
const commentRegex = new RegExp(commentFormat)
const paddedCommentRegex = /^ (\S[\s\S]+\S) $/
const commentStyleRegex = /^( \w+: ("[^"]*"|\d+|false|true),?)+ $/
const chunkSubstrFormat = ` webpackChunkName: "${webpackChunknameFormat}",? `
const chunkSubstrRegex = new RegExp(chunkSubstrFormat)

return {
CallExpression(node) {
Expand All @@ -40,28 +43,64 @@ module.exports = {
const arg = node.arguments[0]
const leadingComments = sourceCode.getComments(arg).leading

if (!leadingComments || leadingComments.length !== 1) {
if (!leadingComments || leadingComments.length === 0) {
context.report({
node,
message: 'dynamic imports require a leading comment with the webpack chunkname',
})
return
}

const comment = leadingComments[0]
if (comment.type !== 'Block') {
context.report({
node,
message: 'dynamic imports require a /* foo */ style comment, not a // foo comment',
})
return
let isChunknamePresent = false

for (const comment of leadingComments) {
if (comment.type !== 'Block') {
context.report({
node,
message: 'dynamic imports require a /* foo */ style comment, not a // foo comment',
})
return
}

if (!paddedCommentRegex.test(comment.value)) {
context.report({
node,
message: `dynamic imports require a block comment padded with spaces - /* foo */`,
})
return
}

try {
// just like webpack itself does
vm.runInNewContext(`(function(){return {${comment.value}}})()`)
}
catch (error) {
context.report({
node,
message: `dynamic imports require a "webpack" comment with valid syntax`,
})
return
}

if (!commentStyleRegex.test(comment.value)) {
context.report({
node,
message:
`dynamic imports require a leading comment in the form /*${chunkSubstrFormat}*/`,
})
return
}

if (chunkSubstrRegex.test(comment.value)) {
isChunknamePresent = true
}
}

const webpackChunkDefinition = comment.value
if (!webpackChunkDefinition.match(commentRegex)) {
if (!isChunknamePresent) {
context.report({
node,
message: `dynamic imports require a leading comment in the form /*${commentFormat}*/`,
message:
`dynamic imports require a leading comment in the form /*${chunkSubstrFormat}*/`,
})
}
},
Expand Down
141 changes: 133 additions & 8 deletions tests/src/rules/dynamic-import-chunkname.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ const parser = 'babel-eslint'

const noLeadingCommentError = 'dynamic imports require a leading comment with the webpack chunkname'
const nonBlockCommentError = 'dynamic imports require a /* foo */ style comment, not a // foo comment'
const commentFormatError = `dynamic imports require a leading comment in the form /* webpackChunkName: "${commentFormat}" */`
const pickyCommentFormatError = `dynamic imports require a leading comment in the form /* webpackChunkName: "${pickyCommentFormat}" */`
const noPaddingCommentError = 'dynamic imports require a block comment padded with spaces - /* foo */'
const invalidSyntaxCommentError = 'dynamic imports require a "webpack" comment with valid syntax'
const commentFormatError = `dynamic imports require a leading comment in the form /* webpackChunkName: "${commentFormat}",? */`
const pickyCommentFormatError = `dynamic imports require a leading comment in the form /* webpackChunkName: "${pickyCommentFormat}",? */`

ruleTester.run('dynamic-import-chunkname', rule, {
valid: [
Expand Down Expand Up @@ -79,6 +81,56 @@ ruleTester.run('dynamic-import-chunkname', rule, {
options,
parser,
},
{
code: `import(
/* webpackChunkName: "someModule", webpackPrefetch: true */
'test'
)`,
options,
parser,
},
{
code: `import(
/* webpackChunkName: "someModule", webpackPrefetch: true, */
'test'
)`,
options,
parser,
},
{
code: `import(
/* webpackPrefetch: true, webpackChunkName: "someModule" */
'test'
)`,
options,
parser,
},
{
code: `import(
/* webpackPrefetch: true, webpackChunkName: "someModule", */
'test'
)`,
options,
parser,
},
{
code: `import(
/* webpackPrefetch: true */
/* webpackChunkName: "someModule" */
'test'
)`,
options,
parser,
},
{
code: `import(
/* webpackChunkName: "someModule" */
/* webpackPrefetch: true */
'test'
)`,
options,
parser,
},
{
code: `import(
/* webpackChunkName: "someModule" */
Expand Down Expand Up @@ -124,7 +176,7 @@ ruleTester.run('dynamic-import-chunkname', rule, {
options,
parser,
errors: [{
message: commentFormatError,
message: invalidSyntaxCommentError,
type: 'CallExpression',
}],
},
Expand All @@ -148,7 +200,7 @@ ruleTester.run('dynamic-import-chunkname', rule, {
options,
parser,
errors: [{
message: commentFormatError,
message: invalidSyntaxCommentError,
type: 'CallExpression',
}],
},
Expand All @@ -164,6 +216,79 @@ ruleTester.run('dynamic-import-chunkname', rule, {
type: 'CallExpression',
}],
},
{
code: `import(
/*webpackChunkName: "someModule"*/
'someModule'
)`,
options,
parser,
errors: [{
message: noPaddingCommentError,
type: 'CallExpression',
}],
},
{
code: `import(
/* webpackChunkName : "someModule" */
'someModule'
)`,
options,
parser,
errors: [{
message: commentFormatError,
type: 'CallExpression',
}],
},
{
code: `import(
/* webpackChunkName: "someModule" ; */
'someModule'
)`,
options,
parser,
errors: [{
message: invalidSyntaxCommentError,
type: 'CallExpression',
}],
},
{
code: `import(
/* totally not webpackChunkName: "someModule" */
'someModule'
)`,
options,
parser,
errors: [{
message: invalidSyntaxCommentError,
type: 'CallExpression',
}],
},
{
code: `import(
/* webpackPrefetch: true */
/* webpackChunk: "someModule" */
'someModule'
)`,
options,
parser,
errors: [{
message: commentFormatError,
type: 'CallExpression',
}],
},
{
code: `import(
/* webpackPrefetch: true, webpackChunk: "someModule" */
'someModule'
)`,
options,
parser,
errors: [{
message: commentFormatError,
type: 'CallExpression',
}],
},
{
code: `import(
/* webpackChunkName: "someModule123" */
Expand All @@ -183,7 +308,7 @@ ruleTester.run('dynamic-import-chunkname', rule, {
)`,
options: multipleImportFunctionOptions,
errors: [{
message: commentFormatError,
message: invalidSyntaxCommentError,
type: 'CallExpression',
}],
},
Expand All @@ -194,7 +319,7 @@ ruleTester.run('dynamic-import-chunkname', rule, {
)`,
options: multipleImportFunctionOptions,
errors: [{
message: commentFormatError,
message: invalidSyntaxCommentError,
type: 'CallExpression',
}],
},
Expand Down Expand Up @@ -224,7 +349,7 @@ ruleTester.run('dynamic-import-chunkname', rule, {
)`,
options,
errors: [{
message: commentFormatError,
message: invalidSyntaxCommentError,
type: 'CallExpression',
}],
},
Expand All @@ -246,7 +371,7 @@ ruleTester.run('dynamic-import-chunkname', rule, {
)`,
options,
errors: [{
message: commentFormatError,
message: invalidSyntaxCommentError,
type: 'CallExpression',
}],
},
Expand Down

0 comments on commit 8d8c20a

Please sign in to comment.