Webpack更改法语unicode字符

时间:2019-06-21 20:10:38

标签: javascript webpack babel

我有一个带有翻译的.js文件。

translations.js

export const translations = {
    common: {
        search: ['Search', 'Rechercher'],
        submit: ['Submit', 'Envoyer'],
        reset: ['Reset', 'Réinitialiser']
    }
};
export default translations;

当我在其上运行webpack build时,一切看起来都很好。但是,当我在开发服务器上执行此操作时,法语的unicode字符(例如é)将替换为“?”。

我不知道为什么在一台计算机上构建它时会添加“?”。当我关闭js uglification时,它仍然存在,因此我认为它是在babel步骤中发生的吗?

package.json

{
  "name": "guests-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "serve:cold": "webpack-dev-server --inline --progress --config build/webpack.cold.conf.js",
    "serve:cold-lan": "webpack-dev-server --inline --progress --config build/webpack.cold.conf.js --host 0.0.0.0",
    "serve:hot": "webpack-dev-server --inline --progress --config build/webpack.hot.conf.js",
    "start": "npm run serve:cold",
    "test": "cross-env BABEL_ENV=test jest",
    "test:watch": "cross-env BABEL_ENV=test jest --watch",
    "lint": "eslint {src/**/*.js*,test/**/*.js*} && exit 0",
    "lint:fix": "eslint {src/**/*.js*,test/**/*.js*} --fix && exit 0",
    "posttest": "npm run lint",
    "build": "node build/build.js"
  },
  "husky": {
    "hooks": {
      "pre-commit": "npm run lint:fix"
    }
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^0.18.0",
    "bootstrap": "^4.3.1",
    "classnames": "^2.2.6",
    "core-js": "^2.6.5",
    "date-fns": "^2.0.0-alpha.34",
    "es6-promise": "^4.2.5",
    "formik": "^1.5.2",
    "prop-types": "^15.6.2",
    "raf": "^3.4.1",
    "react": "^16.8.6",
    "react-bootstrap": "^1.0.0-beta.8",
    "react-datepicker": "^2.4.0",
    "react-dom": "^16.6.0",
    "react-redux": "^5.1.0",
    "react-select": "^2.4.3",
    "react-switch": "^5.0.0",
    "react-virtualized": "^9.21.0",
    "redux": "^4.0.1",
    "redux-thunk": "^2.3.0",
    "yup": "^0.27.0"
  },
  "devDependencies": {
    "autoprefixer": "^7.1.2",
    "axios-mock-adapter": "^1.10.0",
    "babel-cli": "^6.26.0",
    "babel-core": "^6.22.1",
    "babel-eslint": "^7.1.1",
    "babel-jest": "^23.6.0",
    "babel-loader": "^7.1.1",
    "babel-plugin-istanbul": "^4.1.1",
    "babel-plugin-transform-object-assign": "^6.22.0",
    "babel-plugin-transform-runtime": "^6.22.0",
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.3.2",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "babel-preset-stage-2": "^6.22.0",
    "babel-register": "^6.22.0",
    "chalk": "^2.0.1",
    "copy-webpack-plugin": "^4.0.1",
    "cross-env": "^5.0.1",
    "css-loader": "^0.28.0",
    "enzyme": "^3.2.0",
    "enzyme-adapter-react-16": "^1.1.0",
    "enzyme-to-json": "^3.3.4",
    "eslint": "^3.19.0",
    "eslint-config-airbnb-base": "^11.3.0",
    "eslint-friendly-formatter": "^3.0.0",
    "eslint-import-resolver-webpack": "^0.8.3",
    "eslint-loader": "^1.7.1",
    "eslint-plugin-html": "^3.0.0",
    "eslint-plugin-import": "^2.7.0",
    "eslint-plugin-jest": "^22.1.0",
    "eslint-plugin-jsx-a11y": "^6.0.2",
    "eslint-plugin-react": "^7.5.1",
    "eslint-plugin-react-hooks": "^1.6.0",
    "eventsource-polyfill": "^0.9.6",
    "extract-text-webpack-plugin": "^3.0.0",
    "faker": "^4.1.0",
    "file-loader": "^1.1.4",
    "friendly-errors-webpack-plugin": "^1.6.1",
    "html-webpack-plugin": "^2.30.1",
    "husky": "^1.1.3",
    "inject-loader": "^3.0.0",
    "jest": "^23.6.0",
    "node-notifier": "^5.1.2",
    "node-sass": "^4.7.2",
    "optimize-css-assets-webpack-plugin": "^3.2.0",
    "ora": "^1.2.0",
    "phantomjs-prebuilt": "^2.1.14",
    "portfinder": "^1.0.13",
    "postcss-import": "^11.0.0",
    "postcss-loader": "^2.0.8",
    "react-jss": "^8.6.1",
    "react-test-renderer": "^16.6.0",
    "react-text-mask": "^5.1.0",
    "regenerator-runtime": "^0.12.1",
    "rimraf": "^2.6.0",
    "sass-loader": "^6.0.6",
    "semver": "^5.3.0",
    "shelljs": "^0.7.6",
    "style-loader": "^0.19.0",
    "text-mask-addons": "^3.7.1",
    "url-loader": "^0.5.8",
    "webpack": "^3.6.0",
    "webpack-bundle-analyzer": "^2.9.0",
    "webpack-dev-server": "^2.9.1",
    "webpack-merge": "^4.1.0"
  },
  "engines": {
    "node": ">= 4.0.0",
    "npm": ">= 3.0.0"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

build.js

'use strict';
require('./check-versions')();

process.env.NODE_ENV = 'production';

const ora = require('ora');
const rm = require('rimraf');
const path = require('path');
const chalk = require('chalk');
const webpack = require('webpack');
const config = require('../config');
const webpackConfig = require('./webpack.prod.conf');

const spinner = ora('building...');
spinner.start();

rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
  if (err) throw err;
  webpack(webpackConfig, function (err, stats) {
    spinner.stop();
    if (err) throw err;
    process.stdout.write(stats.toString({
      colors: true,
      modules: false,
      children: false,
      chunks: false,
      chunkModules: false
    }) + '\n\n');

    if (stats.hasErrors()) {
      console.log(chalk.red('  Build failed with errors.\n'));
      process.exit(1)
    }

    console.log(chalk.cyan('  Build complete.\n'));
    console.log(chalk.yellow(
      '  Tip: built files are meant to be served over an HTTP server.\n' +
      '  Opening index.html over file:// won\'t work.\n'
    ))
  })
});

webpack.prod.conf.js

const paths = require('./paths');
const utils = require('./utils');
const webpack = require('webpack');
const config = require('../config');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');

const env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : require('../config/prod.env');

const webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true,
      usePostCSS: true
    })
  },
  devtool: config.build.productionSourceMap ? config.build.devtool : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].js'),
    chunkFilename: utils.assetsPath('js/[id].js')
  },
  resolve: {
    alias: {
      settings: `${paths.settings}/dist.js`
    }
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': env
    }),
    // UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      },
      sourceMap: config.build.productionSourceMap,
      parallel: true
    }),
    // extract css into its own file
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].css'),
      // set the following option to `true` if you want to extract CSS from
      // codesplit chunks into this main css file as well.
      // This will result in *all* of your app's CSS being loaded upfront.
      allChunks: false,
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: config.build.productionSourceMap
      ? { safe: true, map: { inline: false } }
      : { safe: true }
    }),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: process.env.NODE_ENV === 'testing'
        ? 'index.html'
        : config.build.index,
      host: '@_host_@',
      template: 'index.html',
      inject: false,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    // keep module.id stable when vender modules does not change
    new webpack.HashedModuleIdsPlugin(),
    // enable scope hoisting
    new webpack.optimize.ModuleConcatenationPlugin(),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks(module) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(paths.nodeModules) === 0
        );
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      minChunks: Infinity
    }),
    // This instance extracts shared chunks from code splitted chunks and bundles them
    // in a separate chunk, similar to the vendor chunk
    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
    new webpack.optimize.CommonsChunkPlugin({
      name: 'app',
      async: 'vendor-async',
      children: true,
      minChunks: 3
    }),

    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: paths.static,
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      }
    ]),

    // copy any extra assets to root dist
    new CopyWebpackPlugin([
      {
        from: `${paths.root}\\web.config`,
        to: config.build.dist,
        ignore: ['.*']
      }
    ])
  ]
});

if (config.build.productionGzip) {
  const CompressionWebpackPlugin = require('compression-webpack-plugin');

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        `\\.(${
        config.build.productionGzipExtensions.join('|')
        })$`
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  );
}

if (config.build.bundleAnalyzerReport) {
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
  webpackConfig.plugins.push(new BundleAnalyzerPlugin());
}

module.exports = webpackConfig;

webpack.base.conf

const paths = require('./paths');
const utils = require('./utils');
const config = require('../config');

module.exports = {
  context: paths.root,
  entry: {
    app: './src/main.jsx'
  },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json'],
    alias: {
      '@': paths.src,
      api: paths.api,
      settings: `${paths.settings}/local.js`,
      enums: paths.enums
    }
  },
  externals: {
    bamboraCheckout: 'customcheckout'
  },
  module: {
    rules: [
      ...(config.dev.useEslint ? [{
        test: /\.js$/,
        loader: 'eslint-loader',
        enforce: 'pre',
        include: [paths.src, paths.test],
        options: {
          formatter: require('eslint-friendly-formatter'),
          emitWarning: !config.dev.showEslintErrorsInOverlay
        }
      }] : []),
      {
        test: /\.(js|jsx|mjs)$/,
        loader: 'babel-loader',
        include: [paths.src, paths.test]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  }
};

dev.env.js

'use strict';
const merge = require('webpack-merge');
const prodEnv = require('./prod.env');

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"'
});

prod.env.js

'use strict';
module.exports = {
  NODE_ENV: '"production"'
};

0 个答案:

没有答案