亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

webpack4 + react 搭建多頁面應用示例

2024-05-06 16:45:31
字體:
來源:轉載
供稿:網友

webpack 升級到4之后還沒好好的同步一個可實用的webpack架子,接下來用webpack4來搭建一個簡單的react的多界面應用,廢話不說 直接擼碼

創建工程

$ mkdir demo && cd demo$ npm init -y

webpack 配置

安裝react + babel 依賴

$ npm i -S react@16.3.0 react-dom@16.3.0$ npm i -D webpack@4.4.1 webpack-cli@2.0.13 webpack-dev-server@3.1.1 webpack-merge@4.1.2 babel-cli@6.26.0 babel-preset-env@1.6.1 babel-preset-react@6.24.1 babel-preset-react-hmre@1.1.1 babel-loader@7.1.4 file-loader@1.1.11 url-loader@1.0.1

webpack.base.conf.js(config -> webpack)

const entry = require("./webpack.entry.conf");const newEntry = {};for (let name in entry) {  newEntry[name] = entry[name][0]}let config = {  entry: newEntry,  resolve: {    extensions: [".js", ".json", ".jsx", ".css", ".pcss"],  }};module.exports = config;

webpack.dev.conf.js

const webpack = require('webpack');//引入webpackconst opn = require('opn');//打開瀏覽器const merge = require('webpack-merge');//webpack配置文件合并const path = require("path");const baseWebpackConfig = require("./webpack.base.conf");//基礎配置const webpackFile = require("./webpack.file.conf");//一些路徑配置const eslintFormatter = require('react-dev-utils/eslintFormatter');let config = merge(baseWebpackConfig, {  /*設置開發環境*/  mode: 'development',  output: {    path: path.resolve(webpackFile.devDirectory),    filename: 'js/[name].js',    chunkFilename: "js/[name].js",    publicPath: ''  },  optimization: {    runtimeChunk: {      name: 'manifest'    },    // 包拆分    splitChunks: {      cacheGroups: {        common: {  // 項目的公共組件          chunks: "initial",          name: "common",          minChunks: 2,          maxInitialRequests: 5,          minSize: 0        },        vendor: {  // 第三方組件          test: /node_modules/,          chunks: "initial",          name: "vendor",          priority: 10,          enforce: true        }      }    }  },  plugins: [    /*設置熱更新*/    new webpack.HotModuleReplacementPlugin(),  ],  module: {    rules: [      {        test: //.(js|jsx)$/,        use: [          'babel-loader',          'cache-loader',        ],        include: [          path.resolve(__dirname, "../../app"),          path.resolve(__dirname, "../../entryBuild")        ],        exclude: [          path.resolve(__dirname, "../../node_modules")        ],      },      {        test: //.(css|pcss)$/,        loader: 'style-loader?sourceMap!css-loader?sourceMap!postcss-loader?sourceMap',        exclude: /node_modules/      },      {        test: //.(png|jpg|gif|ttf|eot|woff|woff2|svg|swf)$/,        loader: 'file-loader?name=[name].[ext]&outputPath=' + webpackFile.resource + '/'      },      {        test: //.(js|jsx)$/,        enforce: 'pre',        use: [          {            options: {              formatter: eslintFormatter,              eslintPath: require.resolve('eslint'),              // @remove-on-eject-begin              baseConfig: {                extends: [require.resolve('eslint-config-react-app')],              },              //ignore: false,              useEslintrc: false,              // @remove-on-eject-end            },            loader: require.resolve('eslint-loader'),          },        ],        include: [          path.resolve(__dirname, "../../app")        ],        exclude: [          path.resolve(__dirname, "../../node_modules")        ],      }    ]  },  /*設置api轉發*/  devServer: {    host: '0.0.0.0',    port: 8080,    hot: true,    inline: true,    contentBase: path.resolve(webpackFile.devDirectory),    historyApiFallback: true,    disableHostCheck: true,    proxy: [      {        context: ['/api/**', '/u/**'],        target: 'http://10.8.200.69:8080/',        secure: false      }    ],    /*打開瀏覽器 并打開本項目網址*/    after() {      opn('http://localhost:' + this.port);    }  }});module.exports = config;

webpack.prod.conf.js

const path = require('path');const merge = require('webpack-merge');const HtmlWebpackPlugin = require('html-webpack-plugin');const CopyWebpackPlugin = require('copy-webpack-plugin');const CleanWebpackPlugin = require('clean-webpack-plugin');const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');const ExtractTextPlugin = require("extract-text-webpack-plugin");const baseWebpackConfig = require("./webpack.base.conf");const webpackFile = require('./webpack.file.conf');const entry = require("./webpack.entry.conf");const webpackCom = require("./webpack.com.conf");let config = merge(baseWebpackConfig, {  /*設置生產環境*/  mode: 'production',  output: {    path: path.resolve(webpackFile.proDirectory),    filename: 'js/[name].[chunkhash:8].js',    chunkFilename: "js/[name]-[id].[chunkhash:8].js",  },  optimization: {    //包清單    runtimeChunk: {      name: "manifest"    },    //拆分公共包    splitChunks: {      cacheGroups: {        common: { //項目公共組件          chunks: "initial",          name: "common",          minChunks: 2,          maxInitialRequests: 5,          minSize: 0        },        vendor: {  //第三方組件          test: /node_modules/,          chunks: "initial",          name: "vendor",          priority: 10,          enforce: true        }      }    }  },  plugins: [    // extract css into its own file    new ExtractTextPlugin('css/[name].[md5:contenthash:hex:8].css'),    // Compress extracted CSS. We are using this plugin so that possible    // duplicated CSS from different components can be deduped.    new OptimizeCSSPlugin({      assetNameRegExp: //.css$/g,      cssProcessor: require('cssnano'),      cssProcessorOptions: {        discardComments: {removeAll: true},        // 避免 cssnano 重新計算 z-index        safe: true      },      canPrint: true    }),  ],  module: {    rules: [      {        test: //.(js|jsx)$/,        use: [          'babel-loader',        ],      },      {        test: //.(js|jsx)$/,        loader: 'babel-loader',        exclude: /node_modules/,      },      {        test: //.(css|pcss)$/,        use: ExtractTextPlugin.extract({          fallback: "style-loader",          use: "css-loader!postcss-loader"        })      },      {        test: //.(png|jpg|gif|ttf|eot|woff|woff2|svg)$/,        loader: 'url-loader?limit=8192&name=[name].[hash:8].[ext]&publicPath=' + webpackFile.resourcePrefix + '&outputPath=' + webpackFile.resource + '/'      },      {        test: //.swf$/,        loader: 'file?name=js/[name].[ext]'      }    ]  }});let pages = entry;for (let chunkName in pages) {  let conf = {    filename: chunkName + '.html',    template: 'index.html',    inject: true,    title: webpackCom.titleFun(chunkName,pages[chunkName][1]),    minify: {      removeComments: true,      collapseWhitespace: true,      removeAttributeQuotes: true    },    chunks: ['manifest', 'vendor', 'common', chunkName],    hash: false,    chunksSortMode: 'dependency'  };  config.plugins.push(new HtmlWebpackPlugin(conf));}/* 清除 dist */config.plugins.push(new CleanWebpackPlugin([webpackFile.proDirectory], {root: path.resolve(__dirname, '../../'), verbose: true, dry: false}));/* 拷貝靜態資源 */copyArr.map(function (data) {  return config.plugins.push(data)});module.exports = config;

構建多界面

整體架構搭建起來之后

app -> component

$ mkdir demo && cd demo$ touch Index.jsx  import React from 'react';  class Index extends React.Component {    render() {      return (        <div className="demo">          寫個demo        </div>      );    }  }    export default Index;

在config -> entry

module.exports = [  {    name: 'index',    path: 'index/Index.jsx',    title: '首頁',    keywords: '首頁',    description: '首頁'  },  {    name: 'demo',    path: 'demo/Index.jsx',    title: 'demo',    keywords: 'demo',    description: 'demo'  },  {    name: 'demo1',    path: 'demo1/Index.jsx',    title: 'demo1',    keywords: 'demo1',    description: 'demo1'  }];

然后直接執行 npm run create-dev 就會在devBuild 和 entryBuild 中添加一個新的demo.html 和 demo.js

package.json{ "name": "webpack_es6", "version": "1.0.0", "description": "", "main": "index.js", "scripts": {  "dev": "webpack-dev-server --devtool eval --progress --colors --profile --config config/webpack/webpack.dev.conf.js",  "entry": "node config/entry/entryBuild.js",  "devBuildHtml": "node config/webpack/webpack.devBuildHtml.conf.js",  "create-dev": "npm run entry && npm run devBuildHtml",  "build": "BABEL_ENV=production && webpack --progress --colors --config config/webpack/webpack.prod.conf.js",  "test": "echo /"Error: no test specified/" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": {  "react": "^16.3.0",  "react-dom": "^16.3.0" }, "devDependencies": {  "babel-cli": "^6.26.0",  "babel-eslint": "^8.2.2",  "babel-loader": "^7.1.4",  "babel-preset-env": "^1.6.1",  "babel-preset-react": "^6.24.1",  "babel-preset-react-hmre": "^1.1.1",  "cache-loader": "^1.2.2",  "clean-webpack-plugin": "^0.1.19",  "copy-webpack-plugin": "^4.5.1",  "css-loader": "^0.28.11",  "eslint": "^4.19.1",  "eslint-config-react-app": "^2.1.0",  "eslint-loader": "^2.0.0",  "eslint-plugin-flowtype": "^2.46.1",  "eslint-plugin-import": "^2.10.0",  "eslint-plugin-jsx-a11y": "^5.1.1",  "eslint-plugin-react": "^7.7.0",  "extract-text-webpack-plugin": "^4.0.0-beta.0",  "file": "^0.2.2",  "file-loader": "^1.1.11",  "html-webpack-plugin": "^3.1.0",  "optimize-css-assets-webpack-plugin": "^4.0.0",  "postcss-cssnext": "^3.1.0",  "postcss-loader": "^2.1.3",  "precss": "^3.1.2",  "react-dev-utils": "^5.0.0",  "style-loader": "^0.20.3",  "url-loader": "^1.0.1",  "webpack": "^4.4.1",  "webpack-cli": "^2.0.13",  "webpack-dev-server": "^3.1.1",  "webpack-merge": "^4.1.2" }, "eslintConfig": {  "extends": "react-app",  "rules": {   "import/no-webpack-loader-syntax": 0,   "no-script-url": 0,   "jsx-a11y/href-no-hash": 2  } }}

開發環境小技巧

在開發環境添加cache-loader 可以提升在開發環境的編譯速度

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
性欧美视频videos6一9| 欧美午夜宅男影院在线观看| 91高潮精品免费porn| 久久精品这里热有精品| 欧美日韩国产丝袜美女| 国产成人高清激情视频在线观看| 亚洲成年网站在线观看| 亚洲综合日韩在线| 日本久久久久久| 国产精品视频不卡| 国产精品视频永久免费播放| www日韩中文字幕在线看| 国产伦精品免费视频| 亚洲淫片在线视频| 亚洲精品中文字幕有码专区| 亚洲午夜国产成人av电影男同| 精品国产视频在线| 久久九九热免费视频| 久久久国产一区| 成人久久一区二区| 2019国产精品自在线拍国产不卡| 欧美日韩中文字幕在线视频| 欧美精品激情视频| 亚洲天堂av在线免费| 亚洲人a成www在线影院| 亚洲欧美日韩中文视频| 亚洲大尺度美女在线| 国产亚洲欧洲黄色| 91亚洲国产成人久久精品网站| 日韩av影院在线观看| 日韩av成人在线观看| 精品国产一区二区三区久久久| 夜夜躁日日躁狠狠久久88av| 亚洲精品欧美一区二区三区| 国产精品视频男人的天堂| 亚洲最大的av网站| 国产精品日韩专区| 日韩精品视频免费专区在线播放| 一夜七次郎国产精品亚洲| 国产精品吴梦梦| 97国产真实伦对白精彩视频8| 欧美中文字幕在线观看| 成人激情电影一区二区| 欧美成人精品不卡视频在线观看| 亚洲图中文字幕| 精品丝袜一区二区三区| 综合国产在线观看| 久久久久久亚洲精品中文字幕| 精品亚洲国产成av人片传媒| 欧美精品激情在线观看| 欧美另类第一页| 亚洲最大的成人网| 国产在线视频一区| 欧美精品一区二区三区国产精品| 欧美日韩成人在线播放| 国产69精品99久久久久久宅男| 中文字幕日韩欧美| 欧美成人精品三级在线观看| 第一福利永久视频精品| 久久久久国色av免费观看性色| 国产精品久久久久久av福利软件| 91社影院在线观看| 在线电影av不卡网址| 亚洲综合社区网| 欧美最猛性xxxxx免费| 九九热这里只有在线精品视| 中日韩美女免费视频网址在线观看| 国产精品美女主播在线观看纯欲| 91国内产香蕉| 亚洲欧洲视频在线| 国产精品美女免费视频| 亚洲精品午夜精品| 91亚洲精品在线| 国产精品电影观看| 播播国产欧美激情| 最近2019中文字幕大全第二页| 日韩精品亚洲精品| 久久九九亚洲综合| 亚洲qvod图片区电影| 亚洲精品第一国产综合精品| 国产精品网红直播| 在线播放日韩av| 97精品免费视频| 性欧美在线看片a免费观看| 日韩国产激情在线| 日韩欧美在线视频免费观看| 最近的2019中文字幕免费一页| 久久久97精品| 欧美午夜性色大片在线观看| 日韩电影免费观看中文字幕| 欧美视频精品一区| 亚洲国产97在线精品一区| 一本色道久久综合亚洲精品小说| 91日本在线观看| 亚洲高清av在线| 日韩欧美中文第一页| 中文字幕日韩av综合精品| 亚洲人a成www在线影院| 久久影院免费观看| 久久精品国产亚洲一区二区| 久久久亚洲成人| 一色桃子一区二区| 国产91九色视频| 国产一区欧美二区三区| 亚洲精品98久久久久久中文字幕| 国产亚洲人成a一在线v站| 中文字幕欧美精品在线| 精品久久在线播放| 国产亚洲成精品久久| 福利二区91精品bt7086| 国产精品揄拍500视频| 久久九九免费视频| 成人在线中文字幕| 亚洲精品少妇网址| 国产亚洲综合久久| 亚洲最大福利视频| 精品欧美aⅴ在线网站| 国产精品免费观看在线| 欧美日韩国产区| 欧美日韩成人网| 国内精品模特av私拍在线观看| 精品性高朝久久久久久久| 国产97在线|日韩| 久久精品欧美视频| 欧美一级片在线播放| 亚洲国产一区二区三区在线观看| 91高清视频免费观看| 欧美在线视频一二三| 亚洲性夜色噜噜噜7777| 亚洲bt欧美bt日本bt| 97婷婷大伊香蕉精品视频| 欧美视频第一页| 亚洲精品99久久久久| 亚洲最大在线视频| 国产一区红桃视频| 久久99久久久久久久噜噜| 日韩高清免费观看| 日韩美女福利视频| 国产成人精品亚洲精品| 欧美一级大片在线免费观看| 国产精品99久久久久久人| 国内精品久久久久影院优| 日韩电视剧免费观看网站| 国产成人高清激情视频在线观看| 久久免费精品视频| 久久久久久久久国产精品| 久久人91精品久久久久久不卡| 海角国产乱辈乱精品视频| 国产欧美欧洲在线观看| 亚洲男女性事视频| 亚洲精品国产精品国自产观看浪潮| 国产精品福利在线| 色樱桃影院亚洲精品影院| 亚洲一区二区精品| 国产日韩欧美在线看| 亚洲美女av在线播放| 久久久亚洲精品视频| 中文字幕欧美日韩精品| 最新亚洲国产精品| 亚洲午夜av久久乱码| 久久久最新网址| 69久久夜色精品国产69乱青草| 在线观看国产精品淫| 日韩中文在线视频|