creamidea / creamidea.github.com

冰糖火箭筒&&蜂蜜甜甜圈
https://creamidea.github.io/
4 stars 4 forks source link

[Webpack]Error: You may need an appropriate loader to handle this file type. #19

Closed creamidea closed 7 years ago

creamidea commented 7 years ago

记录一次在 React 开发的过程中出现下面错误的问题:

ERROR in ./web-src/app.jsx
Module parse failed: C:\Users\xxxyyy\Repository\MemorizingWords\web-src\app.jsx Unexpected token (7:2)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (7:2)
    at Parser.pp$4.raise (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:2221:15)
    at Parser.pp.unexpected (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:603:10)
    at Parser.pp$3.parseExprAtom (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1822:12)
    at Parser.pp$3.parseExprSubscripts (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1715:21)
    at Parser.pp$3.parseMaybeUnary (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1692:19)
    at Parser.pp$3.parseExprOps (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1637:21)
    at Parser.pp$3.parseMaybeConditional (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1620:21)
    at Parser.pp$3.parseMaybeAssign (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1597:21)
    at Parser.pp$3.parseExprList (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:2165:22)
    at Parser.pp$3.parseSubscripts (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1741:35)
    at Parser.pp$3.parseExprSubscripts (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1718:17)
    at Parser.pp$3.parseMaybeUnary (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1692:19)
    at Parser.pp$3.parseExprOps (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1637:21)
    at Parser.pp$3.parseMaybeConditional (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1620:21)
    at Parser.pp$3.parseMaybeAssign (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1597:21)
    at Parser.pp$3.parseExpression (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:1573:21)
    at Parser.pp$1.parseStatement (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:727:47)
    at Parser.pp$1.parseTopLevel (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:638:25)
    at Parser.parse (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:516:17)
    at Object.parse (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\acorn\dist\acorn.js:3098:39)
    at Parser.parse (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\webpack\lib\Parser.js:902:15)
    at DependenciesBlock.<anonymous> (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\webpack\lib\NormalModule.js:104:16)
    at DependenciesBlock.onModuleBuild (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\webpack-core\lib\NormalModuleMixin.js:310:10)
    at nextLoader (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\webpack-core\lib\NormalModuleMixin.js:275:25)
    at C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\webpack-core\lib\NormalModuleMixin.js:259:5
    at Storage.finished (C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\enhanced-resolve\lib\CachedInputFileSystem.js:38:16)
    at C:\Users\xxxyyy\Repository\MemorizingWords\node_modules\graceful-fs\graceful-fs.js:78:16
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:380:3)

跟着 webpack 的代码走,慢慢排查出问题代码出现在这里console.log + grep大法好): 在正则匹配的时候,因为操作系统对于路径的不同表示,导致 this.matchPart(str, obj.include) 会出现不同的结果。

于是有两种修改方式:

将业务代码写出这个样子:

module: {
  loaders: [
    {
      test: /\.jsx$/,
      exclude: /node_modules/,
      include: **path.resolve(__dirname, 'web-src')**,
      loader: "babel",
      query: {
        // plugins: ['transform-runtime', 'transform-react-jsx'],
        cacheDirectory: true,
        presets: ["es2015", "react"]
      }
    }
  ];
}

重点:将 include: __dirname+'/web-src' 改成 path.resolve(__dirname, 'web-src')

if(typeof test === "string") {
  return regExpAsMatcher(new RegExp("^"+test.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")));
}

改成

var os = require('os')
...
if(typeof test === "string") {
  test = /windows/i.test(OS.type()) ? test.split('/').join('\\') : test;
  return regExpAsMatcher(new RegExp("^"+test.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")));
}

最后,从这个错误中我们可以学习到,在写跨平台的操作系统的时候,对于路径问题的处理是需要小心谨慎的。