如何从React组件中的src文件夹导入JavaScript?

时间:2018-09-25 15:08:25

标签: javascript reactjs

我具有以下架构:

my-app/
  README.md
  node_modules/
  package.json
  public/
    favicon.ico
    index.html
  src/
    App.css
    App.js
    App.test.js
    index.css
    index.js
    logo.svg
    recorder.js
    componentsFolder
         Speech.css
         Speech.js

我希望导入能够将recorder.js javascript文件导入到Speech.js,但我没有设法做到这一点,只是使用import或require,因为我总是会遇到以下错误:

我收到以下错误:

./src/components/Speech.js
Module not found: You attempted to import /recorder which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. You can either move it inside src/, or add a symlink to it from project's node_modules/.

所以我相信还有另一种可行的方法。

我附加了两个文件:

Speech.js

import React, { Component } from 'react';
// import './Speech.css';
// import './Speech.css';
import axios from 'axios';
import Recorder from '../recorder'


export default class Speech extends Component {
  constructor(props) {
    super(props);
    this.state = {
      btn: true,
      btnStop: false,
      loader: false,
      result: false,
      resultError: false,
      textResult: '',
      apiKey: 'd9cf10ae33dfbbd03e58d9adfd0a75ef88159d63', // api key
      selected: 'en-US',
      items: [
        {
          text: 'English (United States)',
          value: 'en-US'
        }
      ],
      data: {
        audio: {
          content: null
        },
        config: {
          encoding: 'LINEAR16',
          sampleRateHertz: 44100,
          languageCode: null
        }
      }
    };
  }

  startUserMedia(stream) {
    const input = window.audio_context.createMediaStreamSource(stream);
    // Media stream created

    // const { Recorder: myRecorder } = require('/recorder');
    // console.log(myRecorder);

    // require('/recorder');
    this.recorder = new Recorder(input);
    // Recorder initialised
  }

  startRecording() {
    // Start Recording
    this.recorder && this.recorder.record();
    this.state.result = false;
    this.state.btn = false;
    this.state.btnStop = true;
    setTimeout(this.stopRecording, 58000);
  }

  stopRecording() {
    // Stopped Recording
    this.recorder && this.recorder.stop();
    this.state.btnStop = false;
    this.state.loader = true;
    // create WAV download link using audio data blob
    this.processRecording();
    this.recorder.clear();
  }

  processRecording() {
    const vm = this;

    this.recorder &&
      this.recorder.exportWAV(blob => {
        const reader = new window.FileReader();
        reader.readAsDataURL(blob);
        reader.onloadend = () => {
          const baseData = reader.result;
          const base64Data = baseData.replace('data:audio/wav;base64,', '');
          vm.data.audio.content = base64Data;
          vm.data.config.languageCode = vm.state.selected;
          axios
            .post(
              `https://speech.googleapis.com/v1/speech:recognize?key=${vm.state.apiKey}`,
              vm.data
            )
            .then(response => {
              const result = response.data.results[0].alternatives[0];
              vm.state.textResult = result.transcript;
              vm.state.btn = true;
              vm.state.loader = false;
              vm.state.result = true;
            })
            .catch(error => {
              vm.state.loader = false;
              vm.state.resultError = true;
              console.log(`ERROR:${error}`);
            });
        };
      });
  }

  redirectError() {
    window.location.href = 'http://localhost:8080/';
  }

  componentWillMount() {
    try {
      window.AudioContext = window.AudioContext || window.webkitAudioContext;
      navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
      window.URL = window.URL || window.webkitURL;

      window.audio_context = new AudioContext();
      console.log('Audio context set up.');
      console.log(
        `navigator.getUserMedia ${navigator.getUserMedia ? 'available.' : 'not present!'}`
      );
    } catch (e) {
      alert('No web audio support in this browser!');
    }
    const that = this;
    navigator.getUserMedia(
      {
        audio: true
      },
      stream => {
        that.state.startUserMedia(stream);
      },
      e => {
        console.log(`No live audio input: ${e}`);
      }
    );
  }

  render() {
    return (
      <layout row wrap>
          <select show="btn" items={this.state.items} model="selected" label="Select a language" />
          <button onClick={this.startRecording} block round color="primary" dark>
            <icon left>mic</icon>
            Recording
          </button>
          <button onClick={this.stopRecording} block round color="error" dark>
            <icon left>stop</icon>
            Stop
          </button>
          <div>
            <progress-circle indeterminate size="100" width="3" class="orange--text" />
          </div>
          <transition name="slide">
            <div>
              <layout row wrap>
                  <card className="darken-2 orange--text">
                    <h4 className="text-xs-center">{this.state.textResult}</h4>
                  </card>
              </layout>
            </div>
          </transition>
          <transition name="slide">
            <div v-show="resultError" className="text-xs-center">
              <layout row wrap>
                <col />
                <col>
                  <card className="red darken-3 white--text">
                    <card-title primary-title>
                      <div className="headline">An Unexpected Error Occurred</div>
                    </card-title>
                    <card-actions>
                      <button onClick={this.redirectError} flat dark>
                        Try Again
                      </button>
                    </card-actions>
                  </card>
                </col>
                <col />
              </layout>
            </div>
          </transition>
      </layout>
    );
  }
}

recorder.js

(function (f) {
  if (typeof exports === 'object' && typeof module !== 'undefined') {
    module.exports = f()
  } else if (typeof define === 'function' && define.amd) {
    define([], f)
  } else {
    var g
    if (typeof window !== 'undefined') {
      g = window
    } else if (typeof global !== 'undefined') {
      g = global
    } else if (typeof self !== 'undefined') {
      g = self
    } else {
      g = this
    }
    g.Recorder = f()
  }
})(function () {
  var define, module, exports
  return (function e (t, n, r) {
    function s (o, u) {
      if (!n[o]) {
        if (!t[o]) {
          var a = typeof require === 'function' && require
          if (!u && a) return a(o, !0)
          if (i) return i(o, !0)
          var f = new Error("Cannot find module '" + o + "'")
          throw f.code = 'MODULE_NOT_FOUND', f
        }
        var l = n[o] = {
          exports: {}
        }
        t[o][0].call(l.exports, function (e) {
          var n = t[o][1][e]
          return s(n || e)
        }, l, l.exports, e, t, n, r)
      }
      return n[o].exports
    }
    var i = typeof require === 'function' && require
    for (var o = 0; o < r.length; o++) s(r[o])
    return s
  })({
    1: [function (require, module, exports) {
      'use strict'

      module.exports = require('./recorder').Recorder
    }, {
      './recorder': 2
    }],
    2: [function (require, module, exports) {
      'use strict'

      var _createClass = (function () {
        function defineProperties (target, props) {
          for (var i = 0; i < props.length; i++) {
            var descriptor = props[i]
            descriptor.enumerable = descriptor.enumerable || false
            descriptor.configurable = true
            if ('value' in descriptor) descriptor.writable = true
            Object.defineProperty(target, descriptor.key, descriptor)
          }
        }
        return function (Constructor, protoProps, staticProps) {
          if (protoProps) defineProperties(Constructor.prototype, protoProps)
          if (staticProps) defineProperties(Constructor, staticProps)
          return Constructor
        }
      })()

      Object.defineProperty(exports, '__esModule', {
        value: true
      })
      exports.Recorder = undefined

      var _inlineWorker = require('inline-worker')

      var _inlineWorker2 = _interopRequireDefault(_inlineWorker)

      function _interopRequireDefault (obj) {
        return obj && obj.__esModule ? obj : {
          default: obj
        }
      }

      function _classCallCheck (instance, Constructor) {
        if (!(instance instanceof Constructor)) {
          throw new TypeError('Cannot call a class as a function')
        }
      }

      var Recorder = exports.Recorder = (function () {
        function Recorder (source, cfg) {
          var _this = this

          _classCallCheck(this, Recorder)

          this.config = {
            bufferLen: 4096,
            numChannels: 1,
            mimeType: 'audio/wav'
          }
          this.recording = false
          this.callbacks = {
            getBuffer: [],
            exportWAV: []
          }

          Object.assign(this.config, cfg)
          this.context = source.context
          this.node = (this.context.createScriptProcessor || this.context.createJavaScriptNode).call(this.context, this.config.bufferLen, this.config.numChannels, this.config.numChannels)

          this.node.onaudioprocess = function (e) {
            if (!_this.recording) return

            var buffer = []
            for (var channel = 0; channel < _this.config.numChannels; channel++) {
              buffer.push(e.inputBuffer.getChannelData(channel))
            }
            _this.worker.postMessage({
              command: 'record',
              buffer: buffer
            })
          }

          source.connect(this.node)
          this.node.connect(this.context.destination) // this should not be necessary

          var self = {}
          this.worker = new _inlineWorker2.default(function () {
            var recLength = 0

            var recBuffers = []

            var sampleRate = undefined

            var numChannels = undefined

            self.onmessage = function (e) {
              switch (e.data.command) {
                case 'init':
                  init(e.data.config)
                  break
                case 'record':
                  record(e.data.buffer)
                  break
                case 'exportWAV':
                  exportWAV(e.data.type)
                  break
                case 'getBuffer':
                  getBuffer()
                  break
                case 'clear':
                  clear()
                  break
              }
            }

            function init (config) {
              sampleRate = config.sampleRate
              numChannels = config.numChannels
              initBuffers()
            }

            function record (inputBuffer) {
              for (var channel = 0; channel < numChannels; channel++) {
                recBuffers[channel].push(inputBuffer[channel])
              }
              recLength += inputBuffer[0].length
            }

            function exportWAV (type) {
              var buffers = []
              for (var channel = 0; channel < numChannels; channel++) {
                buffers.push(mergeBuffers(recBuffers[channel], recLength))
              }
              var interleaved = undefined
              if (numChannels === 2) {
                interleaved = interleave(buffers[0], buffers[1])
              } else {
                interleaved = buffers[0]
              }
              var dataview = encodeWAV(interleaved)
              var audioBlob = new Blob([dataview], {
                type: type
              })

              self.postMessage({
                command: 'exportWAV',
                data: audioBlob
              })
            }

            function getBuffer () {
              var buffers = []
              for (var channel = 0; channel < numChannels; channel++) {
                buffers.push(mergeBuffers(recBuffers[channel], recLength))
              }
              self.postMessage({
                command: 'getBuffer',
                data: buffers
              })
            }

            function clear () {
              recLength = 0
              recBuffers = []
              initBuffers()
            }

            function initBuffers () {
              for (var channel = 0; channel < numChannels; channel++) {
                recBuffers[channel] = []
              }
            }

            function mergeBuffers (recBuffers, recLength) {
              var result = new Float32Array(recLength)
              var offset = 0
              for (var i = 0; i < recBuffers.length; i++) {
                result.set(recBuffers[i], offset)
                offset += recBuffers[i].length
              }
              return result
            }

            function interleave (inputL, inputR) {
              var length = inputL.length + inputR.length
              var result = new Float32Array(length)

              var index = 0

              var inputIndex = 0

              while (index < length) {
                result[index++] = inputL[inputIndex]
                result[index++] = inputR[inputIndex]
                inputIndex++
              }
              return result
            }

            function floatTo16BitPCM (output, offset, input) {
              for (var i = 0; i < input.length; i++, offset += 2) {
                var s = Math.max(-1, Math.min(1, input[i]))
                output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true)
              }
            }

            function writeString (view, offset, string) {
              for (var i = 0; i < string.length; i++) {
                view.setUint8(offset + i, string.charCodeAt(i))
              }
            }

            function encodeWAV (samples) {
              var buffer = new ArrayBuffer(44 + samples.length * 2)
              var view = new DataView(buffer)

              /* RIFF identifier */
              writeString(view, 0, 'RIFF')
              /* RIFF chunk length */
              view.setUint32(4, 36 + samples.length * 2, true)
              /* RIFF type */
              writeString(view, 8, 'WAVE')
              /* format chunk identifier */
              writeString(view, 12, 'fmt ')
              /* format chunk length */
              view.setUint32(16, 16, true)
              /* sample format (raw) */
              view.setUint16(20, 1, true)
              /* channel count */
              view.setUint16(22, numChannels, true)
              /* sample rate */
              view.setUint32(24, sampleRate, true)
              /* byte rate (sample rate * block align) */
              view.setUint32(28, sampleRate * 4, true)
              /* block align (channel count * bytes per sample) */
              view.setUint16(32, numChannels * 2, true)
              /* bits per sample */
              view.setUint16(34, 16, true)
              /* data chunk identifier */
              writeString(view, 36, 'data')
              /* data chunk length */
              view.setUint32(40, samples.length * 2, true)

              floatTo16BitPCM(view, 44, samples)

              return view
            }
          }, self)

          this.worker.postMessage({
            command: 'init',
            config: {
              sampleRate: this.context.sampleRate,
              numChannels: this.config.numChannels
            }
          })

          this.worker.onmessage = function (e) {
            var cb = _this.callbacks[e.data.command].pop()
            if (typeof cb === 'function') {
              cb(e.data.data)
            }
          }
        }

        _createClass(Recorder, [{
          key: 'record',
          value: function record () {
            this.recording = true
          }
        }, {
          key: 'stop',
          value: function stop () {
            this.recording = false
          }
        }, {
          key: 'clear',
          value: function clear () {
            this.worker.postMessage({
              command: 'clear'
            })
          }
        }, {
          key: 'getBuffer',
          value: function getBuffer (cb) {
            cb = cb || this.config.callback
            if (!cb) throw new Error('Callback not set')

            this.callbacks.getBuffer.push(cb)

            this.worker.postMessage({
              command: 'getBuffer'
            })
          }
        }, {
          key: 'exportWAV',
          value: function exportWAV (cb, mimeType) {
            mimeType = mimeType || this.config.mimeType
            cb = cb || this.config.callback
            if (!cb) throw new Error('Callback not set')

            this.callbacks.exportWAV.push(cb)

            this.worker.postMessage({
              command: 'exportWAV',
              type: mimeType
            })
          }
        }], [{
          key: 'forceDownload',
          value: function forceDownload (blob, filename) {
            var url = (window.URL || window.webkitURL).createObjectURL(blob)
            var link = window.document.createElement('a')
            link.href = url
            link.download = filename || 'output.wav'
            var click = document.createEvent('Event')
            click.initEvent('click', true, true)
            link.dispatchEvent(click)
          }
        }])

        return Recorder
      })()

      exports.default = Recorder
    }, {
      'inline-worker': 3
    }],
    3: [function (require, module, exports) {
      'use strict'

      module.exports = require('./inline-worker')
    }, {
      './inline-worker': 4
    }],
    4: [function (require, module, exports) {
      (function (global) {
        'use strict'

        var _createClass = (function () {
          function defineProperties (target, props) {
            for (var key in props) {
              var prop = props[key]
              prop.configurable = true
              if (prop.value) prop.writable = true
            }
            Object.defineProperties(target, props)
          }
          return function (Constructor, protoProps, staticProps) {
            if (protoProps) defineProperties(Constructor.prototype, protoProps)
            if (staticProps) defineProperties(Constructor, staticProps)
            return Constructor
          }
        })()

        var _classCallCheck = function (instance, Constructor) {
          if (!(instance instanceof Constructor)) {
            throw new TypeError('Cannot call a class as a function')
          }
        }

        var WORKER_ENABLED = !!(global === global.window && global.URL && global.Blob && global.Worker)

        var InlineWorker = (function () {
          function InlineWorker (func, self) {
            var _this = this

            _classCallCheck(this, InlineWorker)

            if (WORKER_ENABLED) {
              var functionBody = func.toString().trim().match(/^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/)[1]
              var url = global.URL.createObjectURL(new global.Blob([functionBody], {
                type: 'text/javascript'
              }))

              return new global.Worker(url)
            }

            this.self = self
            this.self.postMessage = function (data) {
              setTimeout(function () {
                _this.onmessage({
                  data: data
                })
              }, 0)
            }

            setTimeout(function () {
              func.call(self)
            }, 0)
          }

          _createClass(InlineWorker, {
            postMessage: {
              value: function postMessage (data) {
                var _this = this

                setTimeout(function () {
                  _this.self.onmessage({
                    data: data
                  })
                }, 0)
              }
            }
          })

          return InlineWorker
        })()

        module.exports = InlineWorker
      }).call(this, typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : {})
    }, {}]
  }, {}, [1])(1)
})

2 个答案:

答案 0 :(得分:0)

您指向的文件不存在。您需要从my-app/src/componentsFolder/Speech.js导入../recorder

答案 1 :(得分:0)

当我们看到错误而不是引起错误的代码时,这很困难。我看到了一些问题,希望其中至少有一个问题。

首先,在您提供的树中,App.css位于树的中间,但不包括缩进。我认为这是不正确的,应该位于/ src文件夹中。我不知道结构中是否还有其他错误。

此外,您的错误表明它正在寻找/ recorder。这也会显得不正确。您要查找“ / recorder”还是“ ./recorder”?后者将是首选进口。另外,您是否要使用recorder.js的export,export default或modules.export?