如何使用 Shebang Loader 配置 Webpack 以忽略 Hashbang 将 Cesium React 组件导入 Typescript React 组件

Posted

技术标签:

【中文标题】如何使用 Shebang Loader 配置 Webpack 以忽略 Hashbang 将 Cesium React 组件导入 Typescript React 组件【英文标题】:How to Configure Webpack with Shebang Loader to Ignore Hashbang Importing Cesium React Component into Typescript React Component 【发布时间】:2018-07-31 03:41:33 【问题描述】:

我正在尝试创建一个故事书测试,该测试在使用 typescript、babel 和 webpack 的模块中使用 react 组件。 My Map react 组件引用并使用 cesium 和 cesium-react 组件。

当我尝试运行 start-storybook (yarn storybook) 时出现错误:

ERROR in ./node_modules/requirejs/bin/r.js
Module parse failed: Unexpected character '#' (1:0)
You may need an appropriate loader to handle this file type.
| #!/usr/bin/env node
| /**
|  * @license r.js 2.3.5 Copyright jQuery Foundation and other contributors.
@ ./node_modules/cesium/index.js 5:16-36
@ ./node_modules/cesium-react/dist/cesium-react.es.js
@ ./src/components/Map.js
@ ./stories/map.stories.js
@ ./stories .stories.(ts?x|js)$
@ ./.storybook/config.js
@ multi ./node_modules/@storybook/react/dist/server/config/polyfills.js ./node_modules/@storybook/react/dist/server/config/globals.js (webpack)-hot-middleware/client.js?reload=

如果我用谷歌搜索这个错误“模块解析失败。意外字符“#”。 #4603' 我在结果列表顶部看到类似的问题,建议尝试一些事情。

添加自定义加载程序(参考 4603) 尝试使用 shebang loader(参考 4603/531) 根本不测试(参考 170) 此外,其中一个链接到 jsonstream 的一个非常相似的错误,可以通过谷歌搜索“节点目标应忽略 hashbang #2168”找到该错误

我的主要问题是:

    我曾尝试使用自定义加载程序和 shebang 加载程序(参考 2168),但似乎都不起作用。甚至可以解决这个错误并在故事书中运行吗?关于 JSONstream 的研究表明,使用 shebang 加载程序可以解决问题,但我只是没有正确配置。 假设 shebang loader 是推荐的可能解决方案中最好的,那么我在 .storybook/webpack.config.js 中可能做错了什么(显然我正在做的事情不起作用)。

我应该注意:

如果我不尝试使用 typescript 加载器,我可以让 storybook 运行我的 Map 组件。如果我将 Map 故事添加到来自 github 的 cesium-react 项目的副本,我可以运行它。 此处显示的我的地图组件已尽可能简化,以便尝试识别和解决我的导入问题。但是,其目的是我的实际 Map 组件将使用 Typescript 实现。

这里是我认为相关文件的 sn-ps,但如果被问到,我很乐意发布其他文件或 sn-ps。

.storybook/webpack.config.js

const genDefaultConfig = require('@storybook/react/dist/server/config/defaults/webpack.config.js');
module.exports = (baseConfig, env) => 
  const config = genDefaultConfig(baseConfig, env);
  config.module.rules.push(
    test: /\.(ts|tsx)$/,
    loader: require.resolve('ts-loader')
  );
  // Add shebang to try to workaround unexpected character error.
  config.module.rules.push(
    test: /node_modules\/cesium\/index\.js$/,
    loader: require.resolve('shebang-loader')
  );
  config.resolve.extensions.push('.ts', '.tsx');
  return config;
;

.storybook/config.js

import  configure  from '@storybook/react';

// automatically import all files ending in *.stories.js or *.stories.ts?x
const req = require.context('../stories', true, /.stories.(ts?x|js)$/);

//interates through all files in ../stories that match the regex above
//and adds them to list of stories to show
function loadStories() 
  req.keys().forEach((filename) => req(filename));


configure(loadStories, module);

故事/map.stories.js

import * as React from 'react';
import Map from "../src/components/Map";
import  withInfo  from '@storybook/addon-info';
import  storiesOf  from '@storybook/react';
storiesOf("Map", module)
  .add('Sample Map',
    withInfo('Map Stuff')(() =>
      <Map />
  ));

src/components/Map.js。如果我在 Map.js 中取消注释我的 cesium-react 导入,则会发生错误。

import * as React from 'react';
// Uncomment to see unexpected character error.
import  Viewer  from "cesium-react";
export default class Map extends React.Component 
  render() 
    return (
      <div>hello</div>
    );
  

package.json(sn-p,如果认为有必要,我可以提供更多文件)

"scripts": 
  "test": "jest",
  "test:watch": "jest --watch",
  "test:coverage": "jest --coverage",
  "test:ci":"jest --ci --testResultsProcessor='jest-junit'",
  "build": "webpack",
  "build:prod": "cross-env NODE_ENV=production webpack -p",
  "clean": "yarn clean:storybook-static && yarn clean:build && yarn clean:docs && yarn clean:node_modules",
  "clean:node_modules": "node ./utility/rimraf-standalone.js node_modules",
  "clean:build": "rimraf build",
  "clean:storybook-static": "rimraf storybook-static",
  "clean:docs": "rimraf docs",
  "storybook": "start-storybook -p 6006",
  "build-storybook": "build-storybook",
  "pre:publish": "yarn lint && yarn test && yarn build:prod",
  "lint": "tslint -c config/tslint.json '/src/**/*.ts,tsx'",
  "generate:docs": "typedoc --out ./docs ./src/index.tsx"
,
"devDependencies": 
  "@types/enzyme": "^3.1.6",
  "@types/jest": "^22.0.1",
  "@types/react": "^16.0.34",
  "@types/react-dom": "^16.0.3",
  "@types/react-test-renderer": "^16.0.0",
  "@types/storybook__addon-info": "^3.2.1",
  "@types/storybook__react": "^3.0.6",
  "@babel/core": "^7.0.0-beta.37",
  "@babel/plugin-proposal-class-properties": "^7.0.0-beta.37",
  "@babel/plugin-proposal-export-default-from": "^7.0.0-beta.37",
  "@babel/plugin-proposal-export-namespace-from": "^7.0.0-beta.37",
  "@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.37",
  "@babel/preset-env": "^7.0.0-beta.37",
  "@babel/preset-react": "^7.0.0-beta.37",
  "@storybook/addon-actions": "^3.4.0-alpha.1",
  "@storybook/addon-info": "^3.3.8",
  "@storybook/addon-links": "^3.4.0-alpha.1",
  "@storybook/addon-storyshots": "^3.3.8",
  "@storybook/react": "^3.4.0-alpha.1",
  "babel-core": "^7.0.0-beta.37",
  "babel-eslint": "^8.2.1",
  "babel-loader": "^8.0.0-beta.0",
  "babel-plugin-istanbul": "^4.1.5",
  "cesium": "^1.41.0",
  "cesium-react": "^0.2.0",
  "classnames": "^2.2.5",
  "copy-webpack-plugin": "^4.3.1",
  "cross-env": "^5.1.3",
  "css-loader": "^0.28.8",
  "del-cli": "^1.1.0",
  "eslint": "^4.15.0",
  "eslint-config-prettier": "^2.9.0",
  "eslint-import-resolver-webpack": "^0.8.4",
  "eslint-plugin-babel": "^4.1.2",
  "eslint-plugin-import": "^2.8.0",
  "eslint-plugin-node": "^5.2.1",
  "eslint-plugin-react": "^7.5.1",
  "extract-text-webpack-plugin": "^3.0.2",
  "html-webpack-include-assets-plugin": "^1.0.2",
  "html-webpack-plugin": "^2.30.1",
  "jasmine-core": "^2.8.0",
  "karma": "^2.0.0",
  "karma-chrome-launcher": "^2.2.0",
  "karma-cli": "^1.0.1",
  "karma-coverage": "^1.1.1",
  "karma-jasmine": "^1.1.1",
  "karma-rollup-preprocessor": "^5.1.1",
  "karma-source-map-support": "^1.2.0",
  "npm-run-all": "^4.1.2",
  "optimize-css-assets-webpack-plugin": "^3.2.0",
  "prettier": "^1.10.2",
  "prettier-eslint": "^8.8.1",
  "prettier-eslint-cli": "^4.7.0",
  "prop-types": "^15.6.0",
  "react": "^16.2.0",
  "react-dom": "^16.2.0",
  "react-hot-loader": "^3.1.3",
  "react-router-dom": "^4.2.2",
  "rollup": "^0.54.0",
  "rollup-plugin-babel": "^4.0.0-beta.0",
  "rollup-plugin-commonjs": "^8.2.6",
  "rollup-plugin-node-resolve": "^3.0.2",
  "rollup-plugin-replace": "^2.0.0",
  "rollup-plugin-uglify": "^2.0.1",
  "storybook-addon-jsx": "^5.3.0",
  "style-loader": "^0.19.1",
  "uglify-es": "^3.3.5",
  "webpack": "^3.10.0",
  "webpack-dev-server": "^2.10.1",
  "ts-jest": "^22.0.1",
  "ts-loader": "^3.2.0",
  "tslint": "^5.9.1",
  "tslint-config-airbnb": "^5.4.2",
  "tslint-react": "^3.4.0",
  "typedoc": "^0.9.0",
  "typescript": "^2.6.2",
  "url-loader": "^0.6.2",
  "shebang-loader": "^0.0.1"
,
"dependencies": 
  "react": "^16.2.0",
  "react-dom": "^16.2.0"

【问题讨论】:

同样的问题,但我的配置有点不同。 我接受了提供的唯一答案,但不幸的是,当我收到答案时,我正在从事的项目已经做了一些不同的事情,所以我无法确定答案是否能解决我的问题。跨度> 【参考方案1】:

我不知道你的webpack 配置,这对我来说很奇怪,我以前没见过,但实际上你需要shebang-loader 所以如果你使用npm 运行:

npm install --save shebang-loader

如果你使用yarn,那么运行:

yarn add shebang-loader

之后你必须将use 键放入你的加载器并在其中加载几个加载器,我猜你的代码如下:

    const genDefaultConfig = require('@storybook/react/dist/server/config/defaults/webpack.config.js');
    module.exports = (baseConfig, env) => 
      const config = genDefaultConfig(baseConfig, env);
      config.module.rules.push(
        test: /\.(ts|tsx)$/,
        use: [
            
               loader: require.resolve('ts-loader')
            ,
            
               loader: 'shebang-loader'
            
        ]
      );
      // Add shebang to try to workaround unexpected character error.
      config.module.rules.push(
        test: /node_modules\/cesium\/index\.js$/,
        loader: require.resolve('shebang-loader')
      );
      config.resolve.extensions.push('.ts', '.tsx');
      return config;
    ;

在我的情况下,它变成了如下:

    module: 
        rules: [
            
                test: /\.(js|jsx)$/,
                exclude: /(node_modules\/)/,
                use: [
                    
                        loader: 'babel-loader'
                    ,
                    
                        loader: 'shebang-loader'
                    
                ]
            
       ]
    

希望对你有帮助。

【讨论】:

我认为用--save-dev而不是--save保存shebang-loader会更好【参考方案2】:

我自己创建了这个 webpack.config.js 来规避这个问题:

   var path = require('path');


module.exports = 
  entry: './src/root.jsx',
  output: 
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  ,
module: 
   loaders: [
     
       test:  /\.js$/,
       loader: 'shebang-loader'
     
   ]
 

【讨论】:

以上是关于如何使用 Shebang Loader 配置 Webpack 以忽略 Hashbang 将 Cesium React 组件导入 Typescript React 组件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Shebang Line (Python 虚拟环境)

如何使用 Shebang Line (Python 虚拟环境)

如何使用带有 shebang 的 awk 的多个参数(即#!)?

webpack5不要再用url-loader了

webpack5不要再用url-loader了

如何从 OSX Swift 命令行工具或 shebang 脚本文件显示窗口?