简体   繁体   English

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

[英]How to import a javascript from src folder in a react component?

I have the following architecture: 我有以下架构:

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

I want to import be able to import the recorder.js javascript file to the Speech.js but I've not managed to do it but just using import or require as I always get the following error: 我想导入能够将recorder.js javascript文件导入到Speech.js,但是我没有设法做到这一点,只是使用import或require,因为我总是遇到以下错误:

I get the following error: 我收到以下错误:

./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/.

So I believe there is another way that could actually work. 因此,我相信还有另一种切实可行的方法。

I attach the two files: 我附上两个文件:

Speech.js 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 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)
})

You're pointing to a file that doesn't exist. 您指向的文件不存在。 From my-app/src/componentsFolder/Speech.js you need to import from ../recorder my-app/src/componentsFolder/Speech.js您需要从../recorder导入

It's difficult when we can see the error, but not the code that caused it. 当我们看到错误而不是导致错误的代码时,这很困难。 I see a few issues, and I hope at least one of them is helpful. 我看到了一些问题,希望其中至少有一个问题。

First, in the tree you provided, App.css is in the middle of the tree, but includes no indentation. 首先,在您提供的树中,App.css位于树的中间,但不包含缩进。 I'll assume that is incorrect and should be in the /src folder. 我认为这是不正确的,应该位于/ src文件夹中。 I don't know if there are other errors also in the structure. 我不知道结构中是否还有其他错误。

In addition, your error says it's looking for /recorder. 另外,您的错误表明它正在寻找/ recorder。 This would also appear incorrect. 这也会显得不正确。 Are you looking for '/recorder' or './recorder'? 您要查找“ / recorder”还是“ ./recorder”? The latter would be the preferred import. 后者将是首选进口。 Also, are you using export, export default, or modules.export for the recorder.js? 另外,您是否对记录器.js使用导出,导出默认值或modules.export?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM