webpack#loader TypeScript Examples

The following examples show how to use webpack#loader. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts    From mpflow with MIT License 6 votes vote down vote up
function getImportCode(
  loaderContext: loader.LoaderContext,
  imports: PluginImportMessage['value'][],
  esModule: boolean,
) {
  let code = ''

  const apiUrl = stringifyRequest(loaderContext, require.resolve('./runtime/api'))

  code += esModule
    ? `import ___WXML_LOADER_API_IMPORT___ from ${apiUrl};\n`
    : `var ___WXML_LOADER_API_IMPORT___ = require(${apiUrl})\n`

  for (const item of imports) {
    const { importName, url } = item
    const request = path.isAbsolute(url) ? JSON.stringify(url) : stringifyRequest(loaderContext, url)

    code += esModule ? `import ${importName} from ${request};\n` : `var ${importName} = require(${request});\n`
  }

  return code
}
Example #2
Source File: index.ts    From mpflow with MIT License 6 votes vote down vote up
function getImportCode(
  loaderContext: loader.LoaderContext,
  imports: PluginImportMessage['value'][],
  esModule: boolean,
) {
  let code = ''

  const apiUrl = stringifyRequest(loaderContext, require.resolve('./runtime/api'))

  code += esModule
    ? `import ___WXSS_LOADER_API_IMPORT___ from ${apiUrl};\n`
    : `var ___WXSS_LOADER_API_IMPORT___ = require(${apiUrl})\n`

  for (const item of imports) {
    const { importName, url } = item
    const request = stringifyRequest(loaderContext, url)

    code += esModule ? `import ${importName} from ${request};\n` : `var ${importName} = require(${request});\n`
  }

  return code
}
Example #3
Source File: index.ts    From optimized-images-loader with MIT License 5 votes vote down vote up
/**
 * Optimized images loader
 * Called by webpack
 *
 * @param {Buffer} source Image to optimize
 * @returns {null} Calls the webpack callback once finished
 */
export default function optimizedImagesLoader(this: loader.LoaderContext, source: Buffer): null {
  const callback = this.async() as loader.loaderCallback;

  (async () => {
    const loaderOptions = getOptions(this) as LoaderOptions;

    // parse image options
    const imageOptions = parseQuery(this.resourceQuery, loaderOptions);

    let result: { data: Buffer | string | string[]; info: { width?: number; height?: number; format?: string } };

    // try retrieving the image from cache
    const cacheHash = getHash(source, imageOptions);
    const cached = await getCache(cacheHash, loaderOptions);

    if (cached) {
      result = cached;

      // update image options from cache
      if (cached.imageOptions) {
        (Object.keys(cached.imageOptions) as Array<keyof ImageOptions>).forEach((option: keyof ImageOptions) => {
          (imageOptions[option] as unknown) = cached.imageOptions[option];
        });
      }
    } else {
      // process image
      result = await processImage(source, imageOptions, loaderOptions);

      // cache processed image
      setCache(cacheHash, result.data, result.info, imageOptions, loaderOptions);
    }

    // process further loaders
    const output = processLoaders(this, result.data, result.info, imageOptions, loaderOptions);

    callback(null, output);
  })();

  return null;
}
Example #4
Source File: processLoaders.ts    From optimized-images-loader with MIT License 5 votes vote down vote up
processLoaders = (
  context: loader.LoaderContext,
  image: Buffer | string | string[],
  originalImageInfo: { width?: number; height?: number; format?: string },
  imageOptions: ImageOptions,
  loaderOptions: OptionObject,
): string => {
  // do not apply further loaders if not needed
  if (imageOptions.processLoaders === false) {
    // transform result to a component
    if (imageOptions.component === 'react') {
      return convertToComponent(image.toString(), originalImageInfo, imageOptions, loaderOptions);
    }

    if (Array.isArray(image)) {
      return enrichResult(image, originalImageInfo, imageOptions);
    }

    const output = Buffer.isBuffer(image) ? image.toString() : image;

    return enrichResult(`module.exports = ${JSON.stringify(output)}`, originalImageInfo, imageOptions);
  }

  // create options for further loaders (url-loader & file-loader)
  const furtherLoaderOptions = {
    ...defaultFurtherLoaderOptions,
    ...loaderOptions,
    esModule: false,
  } as OptionObject;

  // replace name
  furtherLoaderOptions.name = replaceName(furtherLoaderOptions.name, originalImageInfo, imageOptions);

  // change extension for converted images
  if (imageOptions.convert && furtherLoaderOptions.name) {
    furtherLoaderOptions.name =
      furtherLoaderOptions.name.indexOf('[ext]') >= 0
        ? furtherLoaderOptions.name.replace('[ext]', imageOptions.convert)
        : (furtherLoaderOptions.name += `.${imageOptions.convert}`);
  }

  // force inlining
  if (imageOptions.forceInline) {
    furtherLoaderOptions.limit = undefined;

    // force url
  } else if (imageOptions.forceUrl) {
    furtherLoaderOptions.limit = -1;
  }

  // build new loader context
  const furtherLoaderContext = { ...context, query: furtherLoaderOptions };

  // get result of url-loader
  const result = urlLoader.call(furtherLoaderContext, image);

  return enrichResult(result, originalImageInfo, imageOptions);
}
Example #5
Source File: index.ts    From mpflow with MIT License 4 votes vote down vote up
wxmlLoader: loader.Loader = function wxmlLoader(content, map) {
  this.async()
  ;(async (): Promise<[string | Buffer, RawSourceMap?]> => {
    const options: Options = getOptions(this) || {}

    validateOptions(
      {
        additionalProperties: false,
        properties: {
          sourceMap: {
            description: 'Enables/Disables generation of source maps',
            type: 'boolean',
          },
          minimize: {
            description: 'Minimize the output',
            type: 'boolean',
          },
          esModule: {
            description: 'Use the ES modules syntax',
            type: 'boolean',
          },
          context: {
            description: 'A custom file context',
            type: 'string',
          },
          name: {
            description: 'The filename template for the target file(s)',
            type: 'string',
          },
          outputPath: {
            description: 'A filesystem path where the target file(s) will be placed',
            type: 'string',
          },
          resolveMustache: {
            description: 'Should transform mustache url to require',
            type: 'boolean',
          },
          importAttributes: {
            description: 'Attributes that indicate how to resolve imports',
            type: 'array',
          },
        },
      },
      options,
      {
        name: 'WXML Loader',
        baseDataPath: 'options',
      },
    )

    // const sourceMap = typeof options.sourceMap === 'boolean' ? options.sourceMap : this.sourceMap
    const sourceMap = false // do not generate sourceMap since wcc compiler don't recognize it
    const minimize = typeof options.minimize === 'boolean' ? options.minimize : this.minimize

    const contentStr = typeof content === 'string' ? content : content.toString('utf8')
    const ast = parser.parse(this.resourcePath, contentStr)

    const { messages } = await pluginRunner([
      importPlugin({
        resolveMustache: options.resolveMustache,
        attributes: options.importAttributes,
      }),
    ]).process(ast, {
      messages: [],
      fs: this.fs,
      context: this.context,
    })

    const imports: PluginImportMessage['value'][] = []
    const childImports: PluginChildImportMessage['value'][] = []
    const replacers: PluginReplaceMessage['value'][] = []
    for (const message of messages) {
      switch (message.type) {
        case 'import':
          imports.push(message.value)
          break
        case 'child-import':
          childImports.push(message.value)
          break
        case 'replacer':
          replacers.push(message.value)
          break
      }
    }

    const result = parser.codegen(ast, {
      sourceMap,
      minimize,
      prevMap: sourceMap ? map : undefined,
    })

    if (sourceMap && result.map) {
      result.map.setSourceContent(this.resourcePath, contentStr)
    }

    const context = options.context || this.rootContext

    const url = interpolateName(this, options.name || '[name].[ext]', {
      context,
      content,
    })

    const outputPath = JSON.stringify(path.posix.join(options.outputPath || '', url))
    const publicPath = `__webpack_public_path__ + ${outputPath}`

    const esModule = typeof options.esModule !== 'undefined' ? options.esModule : false

    const importCode = getImportCode(this, imports, esModule)
    const moduleCode = getModuleCode(result, childImports, replacers, publicPath, esModule, sourceMap)
    const exportCode = getExportCode(esModule)

    return [`${importCode}${moduleCode}${exportCode}`]
  })().then(
    ([content, sourceMap]: [string | Buffer, RawSourceMap?]) => {
      this.callback(null, content, sourceMap)
    },
    err => {
      this.callback(err)
    },
  )
}
Example #6
Source File: index.ts    From mpflow with MIT License 4 votes vote down vote up
wxssLoader: loader.Loader = function wxssLoader(content, map) {
  this.async()
  ;(async (): Promise<[string, RawSourceMap?]> => {
    const options: Options = getOptions(this) || {}

    validateOptions(
      {
        additionalProperties: false,
        properties: {
          sourceMap: {
            description: 'Enables/Disables generation of source maps',
            type: 'boolean',
          },
          esModule: {
            description: 'Use the ES modules syntax',
            type: 'boolean',
          },
          minimize: {
            description: 'Minimize the output',
            type: 'boolean',
          },
        },
      },
      options,
      {
        name: 'WXSS Loader',
        baseDataPath: 'options',
      },
    )

    const sourceMap = typeof options.sourceMap === 'boolean' ? options.sourceMap : this.sourceMap
    const minimize = typeof options.minimize === 'boolean' ? options.minimize : this.minimize

    const result = await postcss([
      importPlugin({
        filter: url => isUrlRequest(url, this.rootContext),
        // urlHandler: url => stringifyRequest(this, url),
      }),
      urlPlugin({
        filter: url => isUrlRequest(url, this.rootContext),
        // urlHandler: url => stringifyRequest(this, url),
      }),
      ...(!minimize
        ? []
        : [
            require('cssnano')({
              preset: 'lite',
            }),
          ]),
    ]).process(content, {
      from: this.resourcePath,
      to: this.resourcePath,
      map: sourceMap
        ? {
            prev: map,
            inline: false,
            annotation: false,
          }
        : false,
    })

    for (const warning of result.warnings()) {
      this.emitWarning(new Warning(warning))
    }

    const imports: PluginImportMessage['value'][] = []
    const childImports: PluginChildImportMessage['value'][] = []
    const replacers: PluginReplaceMessage['value'][] = []

    for (const message of result.messages) {
      switch (message.type) {
        case 'import':
          imports.push(message.value)
          break
        case 'child-import':
          childImports.push(message.value)
          break
        case 'replacer':
          replacers.push(message.value)
          break
      }
    }

    const esModule = typeof options.esModule !== 'undefined' ? options.esModule : false

    const importCode = getImportCode(this, imports, esModule)
    const moduleCode = getModuleCode(result, childImports, replacers, sourceMap, esModule)
    const exportCode = getExportCode(esModule)

    return [`${importCode}${moduleCode}${exportCode}`]
  })().then(
    ([content, sourceMap]: [string, any?]) => {
      this.callback(null, content, sourceMap)
    },
    error => {
      if (error.file) {
        this.addDependency(error.file)
      }
      this.callback(error)
    },
  )
}