Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Webpack插件中插入函数_Javascript_Webpack_Webpack File Loader - Fatal编程技术网

Javascript 在Webpack插件中插入函数

Javascript 在Webpack插件中插入函数,javascript,webpack,webpack-file-loader,Javascript,Webpack,Webpack File Loader,有人知道如何在网页包插件中插入和重用函数吗?就像从我的插件插入该函数myFunction()并从生成的包中调用它一样 背景资料: 我正在替换其他库中某些资产的某些路径 库A使用file1.afm到file14.afm 库B使用file1.trie到file4.trie 我使用文件加载器将这些文件放入包中,然后我需要每个文件: const f1 = require('file1.afm') 每一个文件都是如此 但图书馆A和B正在做如下工作: data = base64.toByteArra

有人知道如何在网页包插件中插入和重用函数吗?就像从我的插件插入该函数
myFunction()
并从生成的包中调用它一样

背景资料:

我正在替换其他库中某些资产的某些路径

  • 库A使用file1.afm到file14.afm
  • 库B使用file1.trie到file4.trie

我使用
文件加载器将这些文件放入包中,然后我需要每个文件:

const f1 = require('file1.afm') 
每一个文件都是如此

但图书馆A和B正在做如下工作:

data = base64.toByteArray(fs.readFileSync('../src/js/somePath/inLibrary/Private/file1.afm', 'base64'));
对于每个文件。我想用包的正确路径替换该路径,但是
\uu dirname
没有帮助。这就是为什么我想使用

我想做的是将其作为一个全局依赖项插入到我的包中,并将其类似于
\uuuu webpack\uu require\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

因此,理论上我会插入
callsites()[0].getFileName()+\uuuu webpack\u require(moduleId)

到目前为止,我的配置如下所示,
webpack file resolver
是我正在使用的当前插件:

const path = require('path')
const webpackTs = require('webpack-config-typescript')
var WebpackFileResolver = require('webpack-file-resolver')


let config = {
  entry: path.join(__dirname, 'src/handler.ts'),
  target: 'node',
  output: {
    filename: 'deploy/handler_[hash].js',
    libraryTarget: 'commonjs',
    path: path.join(__dirname)
  }
}

config = webpackTs.ts(config)
config.module.rules.push({
  test: /\.(ttf|trie|afm)$/,
  loader: "file-loader",
  options: {
    name: "[name].[ext]",
    outputPath: "deploy",
    publicPath: "./"
  },
})

config.plugins.push(new WebpackFileResolver({
  test: /\.(trie|afm)$/,
  serverPath: "./"
}))

module.exports = config 
到目前为止,我得到的是:

const ConcatSource = require("webpack-sources").ConcatSource

function getRequires (options, chunks) {
  return chunks.reduce((c, chunk) => {
    chunk.forEachModule((module) => {
      const deps = module && module.fileDependencies && module.fileDependencies || []
      deps.forEach((filepath) => {
        if(options.test.test(filepath)) {
          c.add({
            path: filepath,
            id: module.id
          })
        }
      })
    })
    return c
  }, new Set())
}

class WebpackFileResolverPlugin {
  constructor(options = {}) {
    this.options = options
  }

  apply(compiler) {
    const options = this.options
    compiler.plugin('compilation', (compilation) => {
      compilation.plugin('optimize-chunk-assets',  (chunks, done) => {
        const requires = getRequires(options, chunks)
        replaceBundleReadDir(compilation, chunks, requires)
        done()
      })
    })
  }
}

function replaceBundleReadDir(compilation, chunks, requires){
    chunks.forEach(function (chunk) {
        chunk.files.forEach(function (fileName) {
            replaceSource(compilation, fileName, requires)
        })
    })
}

function replaceSource(compilation, fileName, requires){
    let result = compilation.assets[fileName].source()
  const source = []
    requires.forEach((require) => {
    let buffer = []
    for (let c of result) {
      if (c !== '\n') {
        buffer.push(c)
      } else {
        const line = buffer.join('')
        const newLine = replaceFsReadDir (require, line)
        if (newLine !== undefined) {
          result = result.replace(line, newLine)
        }
        buffer = []
      }
    }
    })
    compilation.assets[fileName] = new ConcatSource(result)
}

function replaceFsReadDir (require, line) {
  const webpackRequire = '__webpack_require__'
  const fileName = require.path.replace(/^.*[\\\/]/, '')
  const fileStartMarker = line.indexOf(fileName)
  const readDirMarker = line.lastIndexOf('readFile')
  if (fileStartMarker !== -1 && readDirMarker !== -1) {
    let fileEndMarker = line.indexOf(')', fileStartMarker)
    let getEnd = line.slice(fileStartMarker, fileEndMarker + 1)
    fileEndMarker = (getEnd.length > fileName.length + 2) ? line.indexOf(',', fileStartMarker) : fileEndMarker
    const startSlice = line.indexOf('(', readDirMarker) + 1
    const newLine = `${line.slice(0, startSlice)}${webpackRequire}(${require.id})${line.slice(fileEndMarker)}`
    return newLine
  } else {
    return undefined
  }
}

module.exports = WebpackFileResolverPlugin

同时,我将使用以下内容,它非常粗糙,所以我不能真正推荐它

我要做的是将全局函数预先添加到包中,然后将路径替换为当前正在执行的javascript的路径。如有任何想法,将不胜感激

const ConcatSource = require("webpack-sources").ConcatSource

// This is the function I want to use on my bundle
const noRestForTheWicked = `
const __callsites__ = () => {
    const _ = Error.prepareStackTrace;
    Error.prepareStackTrace = (_, stack) => stack;
    const stack = new Error().stack.slice(1);
    Error.prepareStackTrace = _;
    return stack;
}
const __current_file__ = () => {
  const sep = require('path').sep
  let filePieces = __callsites__()[0].getFileName().split(sep)
  return filePieces.slice(0, -1).join(sep) + sep
};

`

function getRequires (options, chunks) {
  return chunks.reduce((c, chunk) => {
    chunk.forEachModule((module) => {
      const deps = module && module.fileDependencies && module.fileDependencies || []
      deps.forEach((filepath) => {
        if(options.test.test(filepath)) {
          c.add({
            path: filepath,
            id: module.id
          })
        }
      })
    })
    return c
  }, new Set())
}

class WebpackFileResolverPlugin {
  constructor(options = {}) {
    this.options = options
  }

  apply(compiler) {
    const options = this.options
    compiler.plugin('compilation', (compilation) => {
      compilation.plugin('optimize-chunk-assets',  (chunks, done) => {
        const requires = getRequires(options, chunks)
        replaceBundleReadDir(compilation, chunks, requires, options)
        done()
      })
    })
  }
}

function replaceBundleReadDir(compilation, chunks, requires, options){
    chunks.forEach(function (chunk) {
        chunk.files.forEach(function (fileName) {
            replaceSource(compilation, fileName, requires, options)
        })
    })
}

function replaceSource(compilation, fileName, requires, options){
    let result = compilation.assets[fileName].source()
  if ('serverPath' in options && options.serverPath !== undefined) {
     // This is where the hacking happens
     result = noRestForTheWicked + result
  }
    requires.forEach((require) => {
    let buffer = []
    for (let c of result) {
      if (c !== '\n') {
        buffer.push(c)
      } else {
        const line = buffer.join('')
        const newLine = replaceFsReadDir (require, line, options)
        if (newLine !== undefined) {
          result = result.replace(line, newLine)
        }
        buffer = []
      }
    }
    })
    compilation.assets[fileName] = new ConcatSource(result)
}

function replaceFsReadDir (require, line, options) {
  const webpackRequire = '__webpack_require__'
  const fileName = require.path.replace(/^.*[\\\/]/, '')
  const fileStartMarker = line.indexOf(fileName)
  const readDirMarker = line.lastIndexOf('readFile')
  if (fileStartMarker !== -1 && readDirMarker !== -1) {
    let fileEndMarker = line.indexOf(')', fileStartMarker)
    let getEnd = line.slice(fileStartMarker, fileEndMarker + 1)
    fileEndMarker = (getEnd.length > fileName.length + 2) ? line.indexOf(',', fileStartMarker) : fileEndMarker
    const startSlice = line.indexOf('(', readDirMarker) + 1
    let importStr = `${webpackRequire}(${require.id})`
    if ('serverPath' in options && options.serverPath !== undefined) {
      // Server Land, brace for impact, inserting the thing
      importStr = `__current_file__() + ${importStr}`
    }
    const newLine = `${line.slice(0, startSlice)}${importStr}${line.slice(fileEndMarker)}`
    return newLine
  } else {
    return undefined
  }
}

module.exports = WebpackFileResolverPlugin

“我使用文件加载器将这些文件放入我的包中,但库A和库B中的路径都是相对于它们的源的,绑定时会断开。”为什么不
import
导入它们,这将解决路径问题?它们被导入到我的代码库中(这就是它们如何到达绑定的方式)。这并不能解决两个库都会尝试在源代码中读取其路径的文件的问题。