簡體   English   中英

react-native-web 如何配置 webpack

[英]react-native-web how to configure webpack

我想打包reaction-native項目直接在web端使用,但是bundle和啟動時一直報錯,我也想打包node_module。 下面是我的配置

 { "name": "testDemo", "version": "0.0.1", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "test": "jest", "lint": "eslint .", "build": "webpack --config webpack.config.js", "deploy": "npm run build && node server.js", "web": "node node_modules/webpack-dev-server/bin/webpack-dev-server -w", "dev": "webpack-dev-server --config webpack.config.dev.js", }, "dependencies": { "@ant-design/react-native": "^3.2.2", "@babel/preset-env": "^7.8.4", "@react-native-community/cli-platform-android": "^4.0.2", "antd-mobile-demo-data": "^0.3.0", "babel-plugin-transform-class-properties": "^6.24.1", "babel-preset-env": "^1.7.0", "babel-preset-es2016": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-preset-react-native": "4.0.0", "china-city-data": "^1.0.1", "clean-webpack-plugin": "^0.1.19", "es3ify-webpack-plugin": "^0.1.0", "json-loader": "^0.5.7", "prop-types": "^15.7.2", "react": "^16.12.0", "react-dom": "^16.12.0", "react-native": "0.61.5", "react-native-modal-dropdown": "^0.7.0", "react-native-modal-layer": "^1.0.4", "react-native-picker": "^4.3.7", "react-native-router-flux": "^4.2.0", "react-native-web": "^0.12.1", "react-native-webpack": "^0.1.1", "rn-wheel-picker-china-region": "^1.0.3", "webpack-node-externals": "^1.7.2", "webpack-visualizer-plugin": "^0.1.11" }, "devDependencies": { "@babel/core": "^7.8.4", "@babel/runtime": "7.8.4", "@react-native-community/eslint-config": "0.0.5", "@types/node": "^13.7.1", "@types/webpack": "^4.41.6", "autoprefixer": "^9.7.4", "babel": "^6.23.0", "babel-core": "^6.26.3", "babel-jest": "24.9.0", "babel-loader": "^6.4.1", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-es2015": "^6.24.1", "babel-preset-latest": "^6.24.1", "babel-runtime": "^6.26.0", "copy-webpack-plugin": "^5.1.1", "css-loader": "^0.28.11", "ejs-loader": "^0.3.5", "eslint": "^6.8.0", "eslint-loader": "^3.0.3", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^5.0.2", "html-loader": "^0.5.5", "html-webpack-plugin": "^3.2.0", "jest": "24.9.0", "loader": "^2.1.1", "metro-react-native-babel-preset": "0.56.4", "postcss-loader": "^3.0.0", "react-native-webpack-server": "^0.9.3", "react-test-renderer": "16.9.0", "style-loader": "^1.1.3", "ts-node": "^8.6.2", "typescript": "^3.7.5", "url-loader": "^3.0.0", "webpack": "^3.12.0", "webpack-cli": "^4.0.0-beta.3", "webpack-dev-server": "2.6.1", "webpack-stats-plugin": "^0.3.1" }, "jest": { "preset": "react-native" } }

 const path = require('path'); const webpack = require('webpack') const htmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextPlugin = require('extract-text-webpack-plugin') const nodeExternals = require('webpack-node-externals'); const StatsPlugin = require('webpack-stats-plugin') const VisualizerPlugin = require('webpack-visualizer-plugin') module.exports = { devtool: 'inline-source-map', entry: { bundle: path.join(__dirname, 'index.web'), }, output: { path: path.resolve(__dirname, 'dist/dc/testDemo/'), publicPath: "/", filename: 'bundle.js', }, /* target: 'node', // in order to ignore built-in modules like path, fs, etc. externals: [nodeExternals()], // in order to ignore all modules in node_modules folder */ module: { rules:[ /*{ test: /\\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } },*/ { test: /\\.(js|jsx)?$/, loader: 'babel-loader', include:path.resolve(__dirname, 'src')}, /* { test: /\\.(js|jsx)$/,exclude: [ path.resolve(__dirname, 'node_modules'), ], },*/ { test: /\\.less$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: [ { loader: "css-loader", options: { // modules: true, // localIdentName: "[local]_[hash:base64:5]" } }, "postcss-loader", "less-loader" ] }), exclude: path.resolve(__dirname, "src") }, { test: /\\.(css|less)$/, include: /node_modules/, use: [{ loader: 'style-loader' // creates style nodes from JS strings }, { loader: 'css-loader', // translates CSS into CommonJS }, { loader: 'less-loader', // compiles Less to CSS options: { javascriptEnabled: true, sourceMap: true }, }], }, { test: /\\.(css|less)$/, exclude: /node_modules/, use: [{ loader: 'style-loader' // creates style nodes from JS strings }, { loader: 'css-loader', // translates CSS into CommonJS options: { modules: true, localIdentName: '[path][name]__[local]--[hash:base64:5]', } }], }, { test: /\\.less$/, use: [ "style-loader", "css-loader", "postcss-loader", `less-loader` ], include: path.resolve(__dirname, "node_modules","@ant-design") }, { test: /\\.s?[ac]ss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: [ { loader: 'css-loader', options: { minimize: true } }, { loader: 'sass-loader', options: { includePaths: [path.resolve(__dirname, './src')] } } ] }) }, { test: /\\.(eot|woff|svg|ttf|woff2|appcache|mp3|mp4|pdf)(\\?|$)/, include: path.resolve(__dirname, "src"), use: [ "file-loader?name=assets/[name].[hash].[ext]" ] }, { test: /\\.(png|jpg|gif)$/, include: path.resolve(__dirname, "src"), use: [ "url-loader?limit=8192&name=assets/[name].[hash].[ext]", ] }, { test: /\\.(csv|tsv)$/, use: [ 'csv-loader' ] }, { test: /\\.xml$/, use: [ 'xml-loader' ] }, { test: /\\.(js|jsx)$/, include: [path.resolve(__dirname, './src')], loader: 'babel-loader', query: { plugins: [], }, }, ] }, resolve: { extensions: ['.js','.jsx'], /*modules: [__dirname, 'node_modules'],*/ alias: { 'react-native$': 'react-native-web', 'react-native-router-flux': path.resolve(__dirname, "node_modules/react-native-router-flux")}, /*alias: { 'react-native': path.join(__dirname, 'node_modules/react-native'), react: path.join(__dirname, 'node_modules/react'), }*/ }, plugins: [ /*["module-resolver", { "alias": { "^react-native$": "react-native-web" } }],*/ new StatsPlugin.StatsWriterPlugin({ fields: null, filename: __dirname + ".stats.json" }), new VisualizerPlugin({ filename: __dirname + ".stats.html" }), new webpack.optimize.CommonsChunkPlugin({ name: [ '.hello-world.bundle', 'vendor.bundle' ] }), new htmlWebpackPlugin({ filename: 'index.html', inject: 'body', template: './index.html', title: 'index title test', minify: { removeComments: true, collapseWhitespace: true } }), ] };

我是菜鳥,用過很多別人的組件,所以在啟動和打包的時候都會報錯。 我怎么解決這個問題? 謝謝

 D:\\Tools\\nvm\\v13.8.0\\node.exe D:\\Tools\\nvm\\v13.8.0\\node_modules\\npm\\bin\\npm-cli.js run dev --scripts-prepend-node-path=auto > testDemo@0.0.1 dev F:\\project\\testDemo > webpack-dev-server --config webpack.config.dev.js Project is running at http://localhost:8080/ webpack output is served from / (node:3572) DeprecationWarning: loaderUtils.parseQuery() received a non-string value which can be problematic, see https://github.com/webpack/loader-utils/issues/56 parseQuery() will be replaced with getOptions() in the next major version of loader-utils. webpack-visualizer-plugin: error writing stats file webpack-visualizer-plugin: error writing stats file Hash: f0590768fbff9e41d941 Version: webpack 3.12.0 Time: 7664ms Asset Size Chunks Chunk Names assets/u789.d179a97b30f355298dc7b0a1f89ec531.png 110 kB [emitted] assets/u83.92db372e6664f83fa936b5974691aaf2.png 8.65 kB [emitted] assets/u889.61df1a3e2ce147ed045ea10b32b4abc6.png 8.78 kB [emitted] bundle.js 8.5 MB 0 [emitted] [big] bundle F:\\project\\testDemo.stats.json 10.4 MB [emitted] [big] index.html 576 bytes [emitted] [0] ./node_modules/react/index.js 190 bytes {0} [built] [1] ./node_modules/react-native-web/dist/index.js 4.41 kB {0} [built] [167] ./src/BroadbandBusiness.js 24.7 kB {0} [built] [195] ./src/app.json 61 bytes {0} [built] [196] multi (webpack)-dev-server/client?http://localhost:8080 ./index.web 40 bytes {0} [built] [197] (webpack)-dev-server/client?http://localhost:8080 5.83 kB {0} [built] [198] ./node_modules/url/url.js 23.3 kB {0} [built] [204] (webpack)-dev-server/node_modules/strip-ansi/index.js 161 bytes {0} [built] [206] ./node_modules/loglevel/lib/loglevel.js 8.61 kB {0} [built] [207] (webpack)-dev-server/client/socket.js 856 bytes {0} [built] [239] (webpack)-dev-server/client/overlay.js 3.6 kB {0} [built] [244] (webpack)/hot nonrecursive ^\\.\\/log$ 170 bytes {0} [built] [246] (webpack)/hot/emitter.js 77 bytes {0} [built] [248] ./index.web.js 407 bytes {0} [built] [608] ./index.js 238 bytes {0} [built] + 594 hidden modules WARNING in ./node_modules/@ant-design/react-native/es/segmented-control/segmented.ios.js 39:47-66 "export 'SegmentedControlIOS' was not found in 'react-native' @ ./node_modules/@ant-design/react-native/es/segmented-control/segmented.ios.js @ ./node_modules/@ant-design/react-native/es/segmented-control/index.js @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web WARNING in ./node_modules/@ant-design/react-native/es/slider/index.js 40:44-50 "export 'Slider' was not found in 'react-native' @ ./node_modules/@ant-design/react-native/es/slider/index.js @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web WARNING in ./node_modules/@ant-design/react-native/es/image-picker/CameraRollPicker.js 84:39-49 "export 'CameraRoll' was not found in 'react-native' @ ./node_modules/@ant-design/react-native/es/image-picker/CameraRollPicker.js @ ./node_modules/@ant-design/react-native/es/image-picker/ImageRoll.js @ ./node_modules/@ant-design/react-native/es/image-picker/index.js @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web WARNING in ./node_modules/@ant-design/react-native/es/action-sheet/index.js 9:12-26 "export 'ActionSheetIOS' was not found in 'react-native' @ ./node_modules/@ant-design/react-native/es/action-sheet/index.js @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in ./node_modules/@react-native-community/viewpager/js/index.js Module not found: Error: Can't resolve './ViewPagerAndroid' in 'F:\\project\\testDemo\\node_modules\\@react-native-community\\viewpager\\js' @ ./node_modules/@react-native-community/viewpager/js/index.js 3:17-46 @ ./node_modules/@ant-design/react-native/es/tabs/Tabs.js @ ./node_modules/@ant-design/react-native/es/tabs/index.js @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in ./node_modules/react-native-collapsible/Accordion.js Module parse failed: Unexpected token (11:19) You may need an appropriate loader to handle this file type. | | export default class Accordion extends Component { | static propTypes = { | sections: PropTypes.array.isRequired, | renderHeader: PropTypes.func.isRequired, @ ./node_modules/@ant-design/react-native/es/accordion/index.js 16:0-61 @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in ./node_modules/react-native-modal-layer/lib/ModalLayerFactory.js Module parse failed: Unexpected token (15:16) You may need an appropriate loader to handle this file type. | options = { | component: (props) => React.createElement(elem, props), | ...elem.modalLayerOptions | }; | else @ ./node_modules/react-native-modal-layer/lib/index.js 3:0-52 @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in ./node_modules/@bang88/react-native-ultimate-listview/src/refreshableScrollView.ios.js Module parse failed: Unexpected token (18:22) You may need an appropriate loader to handle this file type. | | export default class RefreshableScrollView extends ScrollView { | static defaultProps = { | horizontal: false, | scrollEnabled: true, @ ./node_modules/@bang88/react-native-ultimate-listview/src/refreshableScrollView.js 4:0-45 @ ./node_modules/@bang88/react-native-ultimate-listview/index.js @ ./node_modules/@ant-design/react-native/es/list-view/index.js @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in ./node_modules/react-native-modal-popover/lib/Popover.js Module parse failed: Unexpected token (228:16) You may need an appropriate loader to handle this file type. | var computedStyles = this.computeStyles(); | var contentSizeAvailable = this.state.contentSize.width; | return (<react_native_1.Modal transparent visible={visible} onRequestClose={onClose} onDismiss={onDismiss} supportedOrientations={supportedOrientations} onOrientationChange={this.onOrientationChange}> | <react_native_1.View style={[styles.container, !!contentSizeAvailable && styles.containerVisible]}> | @ ./node_modules/react-native-modal-popover/lib/index.js 3:16-36 5:16-36 @ ./node_modules/@ant-design/react-native/es/popover/index.js @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in ./node_modules/@bang88/react-native-ultimate-listview/src/ultimateListView.js Module parse failed: Unexpected token (24:22) You may need an appropriate loader to handle this file type. | | export default class UltimateListView extends Component { | static defaultProps = { | initialNumToRender: 10, | horizontal: false, @ ./node_modules/@bang88/react-native-ultimate-listview/index.js 1:0-53 @ ./node_modules/@ant-design/react-native/es/list-view/index.js @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in ./node_modules/@bang88/react-native-ultimate-listview/src/refreshableScrollView.android.js Module parse failed: Unexpected token (29:22) You may need an appropriate loader to handle this file type. | | export default class RefreshableScrollView extends ScrollView { | static defaultProps = { | horizontal: false, | scrollEnabled: true, @ ./node_modules/@bang88/react-native-ultimate-listview/src/refreshableScrollView.js 3:0-53 @ ./node_modules/@bang88/react-native-ultimate-listview/index.js @ ./node_modules/@ant-design/react-native/es/list-view/index.js @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in ./node_modules/react-native-modal-layer/lib/ModalLayers.js Module parse failed: Unexpected token (37:16) You may need an appropriate loader to handle this file type. | } | render() { | return (<View style={{ flex: 1 }}> | {this.props.children} | <View pointerEvents={'box-none'} style={{ @ ./node_modules/react-native-modal-layer/lib/index.js 1:0-40 @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in ./node_modules/react-native-modal-layer/lib/ModalLayerController.js Module parse failed: Unexpected token (55:25) You may need an appropriate loader to handle this file type. | } | setOptions(options) { | this.options = { ...this.options, ...options }; | } | hide() { @ ./node_modules/react-native-modal-layer/lib/index.js 2:0-58 @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in ./node_modules/react-native-modal-popover/lib/PopoverTouchable.js Module parse failed: Unexpected token (69:16) You may need an appropriate loader to handle this file type. | throw new Error('Popover touchable must have two children and the second one must be Popover'); | } | return (<React.Fragment> | {React.cloneElement(children[0], { | ref: this.setRef, @ ./node_modules/react-native-modal-popover/lib/index.js 9:25-54 @ ./node_modules/@ant-design/react-native/es/popover/index.js @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in ./node_modules/react-native-safe-area-view/index.js Module parse failed: Unexpected token (99:28) You may need an appropriate loader to handle this file type. | | class SafeView extends Component { | static setStatusBarHeight = height => { | _customStatusBarHeight = height; | }; @ ./node_modules/@ant-design/react-native/es/tab-bar/index.js 7:0-55 @ ./node_modules/@ant-design/react-native/es/index.js @ ./src/BroadbandBusiness.js @ ./index.web.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./index.web ERROR in chunk vendor.bundle [entry] bundle.js Conflict: Multiple assets emit to the same filename bundle.js Child html-webpack-plugin for "index.html": 1 asset [0] ./node_modules/html-webpack-plugin/lib/loader.js!./index.html 727 bytes {0} [built] [1] ./node_modules/lodash/lodash.js 541 kB {0} [built] [2] (webpack)/buildin/global.js 509 bytes {0} [built] [3] (webpack)/buildin/module.js 517 bytes {0} [built] webpack: Failed to compile.

看看這個https://necolas.github.io/react-native-web/docs/multi-platform/

// web/webpack.config.js

const path = require('path');
const webpack = require('webpack');

const appDirectory = path.resolve(__dirname, '../');

// This is needed for webpack to compile JavaScript.
// Many OSS React Native packages are not compiled to ES5 before being
// published. If you depend on uncompiled packages they may cause webpack build
// errors. To fix this webpack can be configured to compile to the necessary
// `node_module`.
const babelLoaderConfiguration = {
  test: /\.js$/,
  // Add every directory that needs to be compiled by Babel during the build.
  include: [
    path.resolve(appDirectory, 'index.web.js'),
    path.resolve(appDirectory, 'src'),
    path.resolve(appDirectory, 'node_modules/react-native-uncompiled')
  ],
  use: {
    loader: 'babel-loader',
    options: {
      cacheDirectory: true,
      // The 'metro-react-native-babel-preset' preset is recommended to match React Native's packager
      presets: ['module:metro-react-native-babel-preset'],
      // Re-write paths to import only the modules needed by the app
      plugins: ['react-native-web']
    }
  }
};

// This is needed for webpack to import static images in JavaScript files.
const imageLoaderConfiguration = {
  test: /\.(gif|jpe?g|png|svg)$/,
  use: {
    loader: 'url-loader',
    options: {
      name: '[name].[ext]',
      esModule: false,
    }
  }
};

module.exports = {
  entry: [
    // load any web API polyfills
    // path.resolve(appDirectory, 'polyfills-web.js'),
    // your web-specific entry file
    path.resolve(appDirectory, 'index.web.js')
  ],

  // configures where the build ends up
  output: {
    filename: 'bundle.web.js',
    path: path.resolve(appDirectory, 'dist')
  },

  // ...the rest of your config

  module: {
    rules: [
      babelLoaderConfiguration,
      imageLoaderConfiguration
    ]
  },

  resolve: {
    // This will only alias the exact import "react-native"
    alias: {
      'react-native$': 'react-native-web'
    },
    // If you're working on a multi-platform React Native app, web-specific
    // module implementations should be written in files using the extension
    // `.web.js`.
    extensions: ['.web.js', '.js']
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM