使用elm-assets-loader创建elm-app webpack配置

时间:2018-08-15 11:05:01

标签: webpack elm

我正在尝试将elm-assets-loader添加到使用create-elm-app创建的新项目中。

当我添加配置块时:

{
    loader: 'elm-assets-loader',
    options: { module: 'Assets', tagger: 'AssetPath' }
},

构建脚本说:

./src/Main.elm
Module build failed: Error: Cannot find module '@babel/core'

我对webpack经验不足,但这使它看起来像试图通过babel运行elm。这也很奇怪,因为babel-core位于create-elm-app的devDependencies中。

我发现了这个问题,但不能做很多事情:https://github.com/NoRedInk/elm-assets-loader/issues/9-我试图对装载机进行重新排序,而没有做任何更改。

由elm-appject生成的完整的webpack配置,以及我为elm-assets-loader添加的内容,如下所示:

'use strict';

const autoprefixer = require('autoprefixer');
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const AssetsPlugin = require('assets-webpack-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const getClientEnvironment = require('./env');
const paths = require('../config/paths');

// Webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
const publicPath = paths.servedPath;
// Some apps do not use client-side routing with pushState.
// For these, "homepage" can be set to "." to enable relative asset paths.
const shouldUseRelativeAssetPaths = publicPath === './';
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
const publicUrl = publicPath.slice(0, -1);

// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);

// Note: defined here because it will be used more than once.
const cssFilename = 'static/css/[name].[contenthash:8].css';

// ExtractTextPlugin expects the build output to be flat.
// (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
// However, our output is structured with css, js and media folders.
// To have this structure working with relative paths, we have to use custom options.
const extractTextPluginOptions = shouldUseRelativeAssetPaths
  ? // Making sure that the publicPath goes back to to build folder.
    { publicPath: Array(cssFilename.split('/').length).join('../') }
  : {};

// Enable users to turn on dead code elimination.
const deadCodeElimination =
  process.env.DEAD_CODE_ELIMINATION === 'true'
    ? {
        dead_code: true,
        pure_funcs: [
          '_elm_lang$core$Native_Utils.update',
          'A2',
          'A3',
          'A4',
          'A5',
          'A6',
          'A7',
          'A8',
          'A9',
          'F2',
          'F3',
          'F4',
          'F5',
          'F6',
          'F7',
          'F8',
          'F9'
        ]
      }
    : {};

module.exports = {
  // Don't attempt to continue if there are any errors.
  bail: true,

  entry: [paths.appIndexJs],

  output: {
    // The build folder.
    path: paths.appBuild,

    // Append leading slash when production assets are referenced in the html.
    publicPath: publicPath,

    // Add /* filename */ comments to generated require()s in the output.
    pathinfo: true,

    // Generated JS files.
    filename: 'static/js/[name].[chunkhash:8].js'
  },

  resolve: {
    modules: ['node_modules'],
    extensions: ['.js', '.elm']
  },

  module: {
    noParse: /\.elm$/,

    rules: [
      {
        test: /\.js$/,
        exclude: [/elm-stuff/, /node_modules/],
        loader: require.resolve('babel-loader'),
        query: {
          // Latest stable ECMAScript features
          presets: [
            [
              require.resolve('babel-preset-env'),
              {
                targets: {
                  // React parses on ie 9, so we should too
                  ie: 9,
                  // We currently minify with uglify
                  // Remove after https://github.com/mishoo/UglifyJS2/issues/448
                  uglify: true
                },
                // Disable polyfill transforms
                useBuiltIns: false,
                // Do not transform modules to CJS
                modules: false
              }
            ]
          ],
          plugins: [
            [
              require.resolve('babel-plugin-transform-runtime'),
              {
                helpers: false,
                polyfill: false,
                regenerator: true
              }
            ]
          ]
        }
      },

      {
        test: /\.elm$/,
        exclude: [/elm-stuff/, /node_modules/],
        use: [
          // string-replace-loader works as InterpolateHtmlPlugin for Elm,
          // it replaces all of the %PUBLIC_URL% with the URL of your
          // application, so you could serve static assets outside of the
          // module system.
          {
            loader: require.resolve('string-replace-loader'),
            query: {
              search: '%PUBLIC_URL%',
              replace: publicUrl,
              flags: 'g'
            }
          },
          {
            loader: 'elm-assets-loader',
            options: { module: 'Assets', tagger: 'AssetPath' }
          },
          {
            // Use the local installation of elm-make
            loader: require.resolve('elm-webpack-loader'),
            options: {
              // If ELM_DEBUGGER was set to "true", enable it. Otherwise
              // for invalid values, "false" and as a default, disable it
              debug: process.env.ELM_DEBUGGER === 'true' ? true : false,
              pathToMake: paths.elmMake
            }
          }
        ]
      },

      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract(
          Object.assign(
            {
              fallback: require.resolve('style-loader'),
              use: [
                {
                  loader: require.resolve('css-loader'),
                  options: {
                    minimize: true
                  }
                },
                {
                  loader: require.resolve('postcss-loader'),
                  options: {
                    ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
                    plugins: () => [
                      autoprefixer({
                        browsers: [
                          '>1%',
                          'last 4 versions',
                          'Firefox ESR',
                          'not ie < 9'
                        ]
                      })
                    ]
                  }
                }
              ]
            },
            extractTextPluginOptions
          )
        )
      },

      {
        exclude: [/\.html$/, /\.js$/, /\.elm$/, /\.css$/, /\.json$/, /\.svg$/],
        loader: require.resolve('url-loader'),
        options: {
          limit: 10000,
          name: 'static/media/[name].[hash:8].[ext]'
        }
      },
      // "file" loader for svg
      {
        test: /\.svg$/,
        loader: require.resolve('file-loader'),
        options: {
          name: 'static/media/[name].[hash:8].[ext]'
        }
      }
    ]
  },

  plugins: [
    new AssetsPlugin({ path: paths.appBuild }),

    new DefinePlugin(env.stringified),

    new InterpolateHtmlPlugin(env.raw),

    // Minify the compiled JavaScript.
    new UglifyJsPlugin({
      compress: Object.assign(
        {
          warnings: false
        },
        deadCodeElimination
      ),
      output: {
        comments: false
      }
    }),

    new HtmlWebpackPlugin({
      inject: true,
      template: paths.appHtml,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true
      }
    }),

    // Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
    new ExtractTextPlugin({
      filename: cssFilename
    }),

    // Generate a service worker script that will precache, and keep up to date,
    // the HTML & assets that are part of the Webpack build.
    new SWPrecacheWebpackPlugin({
      // By default, a cache-busting query parameter is appended to requests
      // used to populate the caches, to ensure the responses are fresh.
      // If a URL is already hashed by Webpack, then there is no concern
      // about it being stale, and the cache-busting can be skipped.
      dontCacheBustUrlsMatching: /\.\w{8}\./,
      filename: 'service-worker.js',
      logger(message) {
        if (message.indexOf('Total precache size is') === 0) {
          // This message occurs for every build and is a bit too noisy.
          return;
        }
        if (message.indexOf('Skipping static resource') === 0) {
          // This message obscures real errors so we ignore it.
          // https://github.com/facebookincubator/create-react-app/issues/2612
          return;
        }
        console.log(message);
      },
      minify: true,
      // For unknown URLs, fallback to the index page
      navigateFallback: publicUrl + '/index.html',
      // Ignores URLs starting from /__ (useful for Firebase):
      // https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219
      navigateFallbackWhitelist: [/^(?!\/__).*/],
      // Don't precache sourcemaps (they're large) and build asset manifest:
      staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/]
    })
  ],
  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty'
  }
};

然后由elm-app弹出创建的package.json,还添加了elm-assets-loader:

{
  "name": "assets-loader-test",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "build": "node scripts/build.js",
    "start": "node scripts/start.js",
    "package": "elm-package",
    "make": "elm-make",
    "repl": "elm-repl",
    "reactor": "elm-reactor",
    "test": "elm-test"
  },
  "devDependencies": {
    "assets-webpack-plugin": "^3.5.1",
    "autoprefixer": "^8.0.0",
    "babel-cli": "^6.26.0",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.6.1",
    "babel-runtime": "^6.26.0",
    "chalk": "^2.3.1",
    "clean-webpack-plugin": "^0.1.18",
    "connect-history-api-fallback": "^1.5.0",
    "css-loader": "^0.28.9",
    "dotenv": "^5.0.0",
    "elm": "^0.18.0",
    "elm-assets-loader": "^0.4.0",
    "elm-hot-loader": "0.5.4",
    "elm-test": "^0.18.12",
    "elm-webpack-loader": "^4.4.0",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^1.1.6",
    "html-webpack-plugin": "^2.30.1",
    "http-proxy-middleware": "^0.17.4",
    "minimist": "1.2.0",
    "postcss-loader": "2.1.0",
    "react-dev-utils": "^5.0.0",
    "react-error-overlay": "^4.0.0",
    "string-replace-loader": "^1.3.0",
    "style-loader": "^0.20.2",
    "sw-precache-webpack-plugin": "^0.11.4",
    "url-loader": "^0.6.2",
    "webpack": "^3.11.0",
    "webpack-dev-server": "^2.11.1"
  }
}

任何建议都值得赞赏。

1 个答案:

答案 0 :(得分:1)

我的问题是不了解限定范围的软件包-elm-assets-loader所需的“ @ babel / core @ latest”与我项目中的“ babel-core”不同。添加“ @ babel / core @ latest”解决了该问题。