2016-11-16 07:04:57 +00:00
|
|
|
import loaderUtils from 'loader-utils'
|
2016-10-15 16:17:27 +00:00
|
|
|
|
2016-12-02 01:43:38 +00:00
|
|
|
module.exports = function (content, sourceMap) {
|
2016-10-15 16:17:27 +00:00
|
|
|
this.cacheable()
|
2017-12-05 23:46:06 +00:00
|
|
|
const callback = this.async()
|
|
|
|
const resourcePath = this.resourcePath
|
2016-10-15 16:17:27 +00:00
|
|
|
|
2017-02-22 18:08:49 +00:00
|
|
|
const query = loaderUtils.getOptions(this)
|
2017-12-05 23:46:06 +00:00
|
|
|
|
|
|
|
// Allows you to do checks on the file name. For example it's used to check if there's both a .js and .jsx file.
|
|
|
|
if (query.validateFileName) {
|
|
|
|
try {
|
|
|
|
query.validateFileName(resourcePath)
|
|
|
|
} catch (err) {
|
|
|
|
callback(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-15 16:17:27 +00:00
|
|
|
const name = query.name || '[hash].[ext]'
|
[BUG] Fix emit-file-loader compatibility with Webpack 4 (#4918)
## Context
When upgrading to Next.js 6.1.1-canary.4 and using the `emit-file-loader` included in Next.js, the following error is thrown:
```bash
error in ./src/graveyard/pages/_app.scss
Module build failed (from ../node_modules/next/dist/build/webpack/loaders/emit-file-loader.js):
TypeError: Cannot read property 'context' of undefined
at Object.module.exports (~/project-root/node_modules/next/dist/build/webpack/load
ers/emit-file-loader.js:27:68)
@ ./src/pages/_app.js 35:0-53 156:17-26 157:13-22
@ multi ./pages/_app.js
```
`next.config.js` (shortened):
```js
module.exports = {
webpack: (config, { dev }) => {
config.module.rules.push({
test: /\.scss$/,
use: [
{
loader: 'emit-file-loader',
options: {
name: 'dist/[path][name].[ext].js'
}
},
{
loader: 'babel-loader',
options: {
babelrc: false,
extends: path.resolve(__dirname, './src/.babelrc')
}
},
'styled-jsx-css-loader',
{ loader: 'postcss-loader', options: { sourceMap: dev } },
{
loader: 'sass-loader',
options: {
sourceMap: dev
}
}
]
});
return config;
}
};
```
## Suggested Fix
A quick Google search brought me to a [related issue in `webpack-loader`](https://github.com/webpack-contrib/worker-loader/issues/125). As pointed out in the [Webpack docs](https://webpack.js.org/api/loaders/#this-rootcontext):
> Starting with webpack 4, the formerly `this.options.context` is provided as `this.rootContext`.
This PR makes this change while maintaining backward compatibility.
## System information
Next.js: 6.1.1-canary.4
Node: v9.3.0
2018-08-07 20:49:30 +00:00
|
|
|
const context = query.context || this.rootContext || this.options.context
|
2016-10-15 16:17:27 +00:00
|
|
|
const regExp = query.regExp
|
|
|
|
const opts = { context, content, regExp }
|
2017-12-05 23:46:06 +00:00
|
|
|
const interpolateName = query.interpolateName || ((name) => name)
|
|
|
|
const interpolatedName = interpolateName(loaderUtils.interpolateName(this, name, opts), {name, opts})
|
2017-01-31 06:31:27 +00:00
|
|
|
const emit = (code, map) => {
|
|
|
|
this.emitFile(interpolatedName, code, map)
|
2017-12-05 23:46:06 +00:00
|
|
|
callback(null, code, map)
|
2017-01-31 06:31:27 +00:00
|
|
|
}
|
2016-10-15 16:17:27 +00:00
|
|
|
|
2017-01-31 06:31:27 +00:00
|
|
|
if (query.transform) {
|
2017-02-01 06:17:15 +00:00
|
|
|
const transformed = query.transform({ content, sourceMap, interpolatedName })
|
2017-01-31 06:31:27 +00:00
|
|
|
return emit(transformed.content, transformed.sourceMap)
|
|
|
|
}
|
|
|
|
|
|
|
|
return emit(content, sourceMap)
|
2016-10-15 16:17:27 +00:00
|
|
|
}
|