Repository: nuxt/nuxt.js
Pull request #6566 (2019-10-14 21:51:30)

fix(webpack): normalize devtool for terser compatibility
<!--- Provide a general summary of your changes in the title above -->

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (a non-breaking change which fixes an issue)
- [ ] New feature (a non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)


## Description
<!--- Describe your changes in detail -->
<!--- Why is this change required? What problem does it solve? -->
<!--- If it resolves an open issue, please link to the issue here. For example "Resolves: #1337" -->

Some modules are using `#source-map` as devtool, this pr is for supporting those modules usage.

## Checklist:
<!--- Put an `x` in all the boxes that apply. -->
<!--- If your change requires a documentation PR, please link it appropriately -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly. (PR: #)
- [ ] I have added tests to cover my changes (if not applicable, please state why)
- [ ] All new and existing tests are passing.



codecov-io: # [Codecov](https://codecov.io/gh/nuxt/nuxt.js/pull/6566?src=pr&el=h1) Report
> Merging [#6566](https://codecov.io/gh/nuxt/nuxt.js/pull/6566?src=pr&el=desc) into [dev](https://codecov.io/gh/nuxt/nuxt.js/commit/a42453bb0cc124c161967e966ea48a2a92fa406b?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/nuxt/nuxt.js/pull/6566/graphs/tree.svg?width=650&token=nGD1PtMB3M&height=150&src=pr)](https://codecov.io/gh/nuxt/nuxt.js/pull/6566?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##              dev    #6566   +/-   ##
=======================================
  Coverage   95.85%   95.85%           
=======================================
  Files          78       78           
  Lines        2705     2705           
  Branches      699      699           
=======================================
  Hits         2593     2593           
  Misses         97       97           
  Partials       15       15
```

| Flag | Coverage Δ | |
|---|---|---|
| #e2e | `100% <ø> (ø)` | :arrow_up: |
| #fixtures | `64.73% <ø> (ø)` | :arrow_up: |
| #unit | `92.31% <ø> (ø)` | :arrow_up: |

| [Impacted Files](https://codecov.io/gh/nuxt/nuxt.js/pull/6566?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [packages/webpack/src/config/base.js](https://codecov.io/gh/nuxt/nuxt.js/pull/6566/diff?src=pr&el=tree#diff-cGFja2FnZXMvd2VicGFjay9zcmMvY29uZmlnL2Jhc2UuanM=) | `92.07% <ø> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/nuxt/nuxt.js/pull/6566?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/nuxt/nuxt.js/pull/6566?src=pr&el=footer). Last update [a42453b...db90e07](https://codecov.io/gh/nuxt/nuxt.js/pull/6566?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/examples/with-sockets/io/index.js b/examples/with-sockets/io/index.js
index 753039a53..ffbda8dd2 100644
--- a/examples/with-sockets/io/index.js
+++ b/examples/with-sockets/io/index.js
@@ -2,23 +2,25 @@ import http from 'http'
 import socketIO from 'socket.io'
 
 export default function () {
-  const server = http.createServer(this.nuxt.renderer.app)
-  const io = socketIO(server)
+  this.nuxt.hook('render:before', (renderer) => {
+    const server = http.createServer(this.nuxt.renderer.app)
+    const io = socketIO(server)
 
-  // overwrite nuxt.server.listen()
-  this.nuxt.server.listen = (port, host) => new Promise(resolve => server.listen(port || 3000, host || 'localhost', resolve))
-  // close this server on 'close' event
-  this.nuxt.hook('close', () => new Promise(server.close))
+    // overwrite nuxt.server.listen()
+    this.nuxt.server.listen = (port, host) => new Promise(resolve => server.listen(port || 3000, host || 'localhost', resolve))
+    // close this server on 'close' event
+    this.nuxt.hook('close', () => new Promise(server.close))
 
-  // Add socket.io events
-  const messages = []
-  io.on('connection', (socket) => {
-    socket.on('last-messages', function (fn) {
-      fn(messages.slice(-50))
-    })
-    socket.on('send-message', function (message) {
-      messages.push(message)
-      socket.broadcast.emit('new-message', message)
+    // Add socket.io events
+    const messages = []
+    io.on('connection', (socket) => {
+      socket.on('last-messages', function (fn) {
+        fn(messages.slice(-50))
+      })
+      socket.on('send-message', function (message) {
+        messages.push(message)
+        socket.broadcast.emit('new-message', message)
+      })
     })
   })
 }
diff --git a/packages/config/src/options.js b/packages/config/src/options.js
index 243f673eb..e05c41292 100644
--- a/packages/config/src/options.js
+++ b/packages/config/src/options.js
@@ -241,9 +241,16 @@ export function getNuxtConfig (_options) {
       allowedSources: undefined,
       policies: undefined,
       addMeta: Boolean(options._generate),
-      unsafeInlineCompatiblity: false,
+      unsafeInlineCompatibility: false,
       reportOnly: options.debug
     })
+
+    // TODO: Remove this if statement in Nuxt 3, we will stop supporting this typo (more on: https://github.com/nuxt/nuxt.js/pull/6583)
+    if (options.render.csp.unsafeInlineCompatiblity) {
+      consola.warn('Using `unsafeInlineCompatiblity` is deprecated and will be removed in Nuxt 3. Use `unsafeInlineCompatibility` instead.')
+      options.render.csp.unsafeInlineCompatibility = options.render.csp.unsafeInlineCompatiblity
+      delete options.render.csp.unsafeInlineCompatiblity
+    }
   }
 
   // cssSourceMap
diff --git a/packages/vue-app/template/client.js b/packages/vue-app/template/client.js
index a0fb5b37b..0c2a44b75 100644
--- a/packages/vue-app/template/client.js
+++ b/packages/vue-app/template/client.js
@@ -40,7 +40,7 @@ Object.assign(Vue.config, <%= serialize(vue.config) %>)<%= isTest ? '// eslint-d
 const logs = NUXT.logs || []
   if (logs.length > 0) {
   const ssrLogSyle = 'background: #2E495E;border-radius: 0.5em;color: white;font-weight: bold;padding: 2px 0.5em;'
-  console.group && console.group <%= nuxtOptions.render.ssrLog === 'collapsed' ? 'Collapsed' : '' %> ("%cNuxt SSR", ssrLogSyle)
+  console.group && console.group<%= nuxtOptions.render.ssrLog === 'collapsed' ? 'Collapsed' : '' %> ("%cNuxt SSR", ssrLogSyle)
   logs.forEach(logObj => (console[logObj.type] || console.log)(...logObj.args))
   delete NUXT.logs
   console.groupEnd && console.groupEnd()
diff --git a/packages/vue-renderer/src/renderers/ssr.js b/packages/vue-renderer/src/renderers/ssr.js
index 410a9c3a3..954fc71cc 100644
--- a/packages/vue-renderer/src/renderers/ssr.js
+++ b/packages/vue-renderer/src/renderers/ssr.js
@@ -138,7 +138,7 @@ export default class SSRRenderer extends BaseRenderer {
     if (csp) {
       // Only add the hash if 'unsafe-inline' rule isn't present to avoid conflicts (#5387)
       const containsUnsafeInlineScriptSrc = csp.policies && csp.policies['script-src'] && csp.policies['script-src'].includes(`'unsafe-inline'`)
-      if (csp.unsafeInlineCompatiblity || !containsUnsafeInlineScriptSrc) {
+      if (csp.unsafeInlineCompatibility || !containsUnsafeInlineScriptSrc) {
         const hash = crypto.createHash(csp.hashAlgorithm)
         hash.update(serializedSession)
         cspScriptSrcHashes.push(`'${csp.hashAlgorithm}-${hash.digest('base64')}'`)
diff --git a/packages/webpack/src/config/base.js b/packages/webpack/src/config/base.js
index 19f56bf70..0a9425b67 100644
--- a/packages/webpack/src/config/base.js
+++ b/packages/webpack/src/config/base.js
@@ -439,11 +439,16 @@ export default class WebpackBaseConfig {
     if (typeof extend === 'function') {
       const extendedConfig = extend.call(
         this.builder, config, { loaders: this.loaders, ...this.nuxtEnv }
-      )
-      // Only overwrite config when something is returned for backwards compatibility
-      if (extendedConfig !== undefined) {
-        return extendedConfig
+      ) || config
+
+      const pragma = /@|#/
+      const { devtool } = extendedConfig
+      if (typeof devtool === 'string' && pragma.test(devtool)) {
+        extendedConfig.devtool = devtool.replace(pragma, '')
+        consola.warn(`devtool has been normalized to ${extendedConfig.devtool} as webpack documented value`)
       }
+
+      return extendedConfig
     }
     return config
   }


Test patch:
diff --git a/packages/config/test/options.test.js b/packages/config/test/options.test.js
index 87166c45c..717680a6b 100644
--- a/packages/config/test/options.test.js
+++ b/packages/config/test/options.test.js
@@ -102,7 +102,21 @@ describe('config: options', () => {
     expect(csp).toEqual({
       hashAlgorithm: 'sha256',
       addMeta: false,
-      unsafeInlineCompatiblity: false,
+      unsafeInlineCompatibility: false,
+      allowedSources: true,
+      policies: undefined,
+      reportOnly: false,
+      test: true
+    })
+  })
+
+  // TODO: Remove this test in Nuxt 3, we will stop supporting this typo (more on: https://github.com/nuxt/nuxt.js/pull/6583)
+  test('should enable csp with old typo property name, avoiding breaking changes', () => {
+    const { render: { csp } } = getNuxtConfig({ render: { csp: { allowedSources: true, test: true, unsafeInlineCompatiblity: true } } })
+    expect(csp).toEqual({
+      hashAlgorithm: 'sha256',
+      addMeta: false,
+      unsafeInlineCompatibility: true,
       allowedSources: true,
       policies: undefined,
       reportOnly: false,
diff --git a/test/fixtures/with-config/nuxt.config.js b/test/fixtures/with-config/nuxt.config.js
index 40289390d..d3cd57827 100644
--- a/test/fixtures/with-config/nuxt.config.js
+++ b/test/fixtures/with-config/nuxt.config.js
@@ -86,7 +86,7 @@ export default {
     transpile: 'vue-test',
     extend (config, options) {
       return Object.assign({}, config, {
-        devtool: '#source-map'
+        devtool: 'source-map'
       })
     }
   },
diff --git a/test/unit/basic.ssr.csp.test.js b/test/unit/basic.ssr.csp.test.js
index b5fa67685..94716cc57 100644
--- a/test/unit/basic.ssr.csp.test.js
+++ b/test/unit/basic.ssr.csp.test.js
@@ -198,7 +198,34 @@ describe('basic ssr csp', () => {
     )
 
     test(
-      'Contain hash and \'unsafe-inline\' when unsafeInlineCompatiblity is enabled',
+      'Contain hash and \'unsafe-inline\' when unsafeInlineCompatibility is enabled',
+      async () => {
+        const policies = {
+          'script-src': [`'unsafe-inline'`]
+        }
+
+        nuxt = await startCspServer({
+          unsafeInlineCompatibility: true,
+          policies
+        })
+
+        for (let i = 0; i < 5; i++) {
+          await rp(url('/stateless'), {
+            resolveWithFullResponse: true
+          })
+        }
+
+        const { headers } = await rp(url('/stateful'), {
+          resolveWithFullResponse: true
+        })
+
+        expect(headers[cspHeader]).toMatch(/script-src 'sha256-.*' 'self' 'unsafe-inline'$/)
+      }
+    )
+
+    // TODO: Remove this test in Nuxt 3, we will stop supporting this typo (more on: https://github.com/nuxt/nuxt.js/pull/6583)
+    test(
+      'Contain hash and \'unsafe-inline\' when the typo property unsafeInlineCompatiblity is enabled',
       async () => {
         const policies = {
           'script-src': [`'unsafe-inline'`]
@@ -419,7 +446,34 @@ describe('basic ssr csp', () => {
     )
 
     test(
-      'Contain hash and \'unsafe-inline\' when unsafeInlineCompatiblity is enabled',
+      'Contain hash and \'unsafe-inline\' when unsafeInlineCompatibility is enabled',
+      async () => {
+        const policies = {
+          'script-src': [`'unsafe-inline'`]
+        }
+
+        nuxt = await startCspServer({
+          unsafeInlineCompatibility: true,
+          policies
+        })
+
+        for (let i = 0; i < 5; i++) {
+          await rp(url('/stateless'), {
+            resolveWithFullResponse: true
+          })
+        }
+
+        const { headers } = await rp(url('/stateful'), {
+          resolveWithFullResponse: true
+        })
+
+        expect(headers[cspHeader]).toMatch(/script-src 'sha256-.*' 'self' 'unsafe-inline'$/)
+      }
+    )
+
+    // TODO: Remove this test in Nuxt 3, we will stop supporting this typo (more on: https://github.com/nuxt/nuxt.js/pull/6583)
+    test(
+      'Contain hash and \'unsafe-inline\' when the typo property unsafeInlineCompatiblity is enabled',
       async () => {
         const policies = {
           'script-src': [`'unsafe-inline'`]