最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • react + webpack 项目搭建

    正文概述 掘金(哗哒哒勒)   2020-12-31   599

    常用配置说明

    • entry

      • 可以接受字符串,数组,对象等多种格式
      • 项目打包入口文件,可以是绝对路径也可以是相对路径
      • webpack 打包默认入口文件是 ./src/index.js 约定,默认输出是 项目根目录下 /dist/main.js
    • output 打包后的内容输出相关配置,path打包后文件路径, 只能使用绝对路径

    • 常用loader相关理解

      • 默认情况下,webpack 值支持.js,.json文件,通过 loader,可以让他解析其他类型的文件(.css, .less, .ts, .vue ....),充当翻译官的角色。理论上只要有响应的 loader,就可以处理任何文件。一个 loader 只干一件事,webpack 的约定
      • 同一后缀文件使用多个 loader 时,loader 有执行顺序,从右向左依次执行
      • css-loader只是把 css 代码打包进 js 文件而已,并不做任何操作
      • style-loader 提取css-loader打包后的css代码,并自动生成标签,然后插入 html 中
      • less-loader 只是把 less 语法编译为 css 语法,然后 css-loader 把编译好的 css 内容插入 js 文件中,最后 style-loader 把 css 添加到标签并动态插入到 html 文件标签中
      • postcss-loader使用顺序,放在能够拿到 css 内容的地方就可以,拿到 css 内容,通过一些 js 插件处理 css 达到增强 css 的效果
    • loader 和 plugin 区别:loader 的主要职责是让 webpack 认识更多的文件类型,而 plugin 的职责是让其可以控制构建流程,从而执行一些特殊的任务。相当于 webpack 的功能补充。

    hash,chunkhash,contenthash

    如果不指定 hash 类型,webpack 默认是用 hash。

    文件使用 hash 名的目的是为了利用浏览器的缓存,当我们做下次功能迭代的时候,只修改某一个文件的时候,hash 发生变化, 但是其他文件没有变化,hash 不变则会走缓存,变化的就会重新请求,这样可以减少请求

    1. hash 是随整个工程内容的变化而变化
    2. chunkhash 只影响一个 chunk 下的模块,一个文件所依赖的代码块会打包进一个 chunk
    3. contenthash 只根据自身的内容变化 而变化, 但是如果 contenthash 发生变化,他所属的 chunkhash 也会变化

    项目目录结构

    .  
    |-- src                             项目源代码  
      |-- components                    项目通用组件
      |-- pages                         项目功能模块
        |-- index.js                    项目入口文件
    |-- static                          项目静态资源,图片,字体文件  
    |-- webpack                         webpack 打包相关的配置  
      |-- config.js                     通用配置变量抽离
      |-- webpack.config.common.js      webpack 公共配置
      |-- webpack.config.dev.js         本地开发环境打包配置
      |-- webpack.config.production.js  正式环境打包配置
      |-- config.js
    |-- index.html                      打包模板
    |-- .babelrc                        babel 相关配置文件
    |-- postcss.config.js               postcss 相关配置文件
    |-- .npmrc                          npm 安装源设置
    |-- package.json         
    

    完整的项目打包方案

    webpack.config.common.js

    const path = require('path');
    const { CleanWebpackPlugin } = require("clean-webpack-plugin");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const webpack = require("webpack");
    
    module.exports = {
      entry: {
        index: './src/pages/index.js',
      },
      resolve: {
        // 项目路径别名
        alias: {
          Utils: path.resolve(__dirname, "../src/utils"),
          Components: path.resolve(__dirname, "../src/components"),
        },
      },
      performance: {
        // false | "error" | "warning" // 不显示性能提示 | 以错误形式提示 | 以警告...
        hints: false,
        // 开发环境设置较大防止警告
        // 根据入口起点的最大体积,控制webpack何时生成性能提示,整数类型,以字节为单位
        maxEntrypointSize: 5000000,
        // 最大单个资源体积,默认250000 (bytes)
        maxAssetSize: 3000000,
      },
      module: {
        rules: [
          {
            test: /\.(js|jsx)$/,
            use: 'babel-loader',
            include: path.resolve(__dirname, "../src"),
            exclude: /node_modules/,
          },
        ]
      },
      plugins: [
        new CleanWebpackPlugin(), // 每次打包前先清除之前的打包内容
        new HtmlWebpackPlugin({
          template: "./index.html", // 打包 html 模板
          filename: "index.html", // 打包后生成的文件名
        }),
        new webpack.DefinePlugin({ // 自定义项目环境变量,此处用于二级目录部署
          "process.env": {
            SECONDARY_PATH: JSON.stringify(process.env.SECONDARY_PATH),
          },
        }),
      ]
    }
    

    webpack.config.dev.js

    const path = require("path");
    const config = require("./config");
    const webpack = require("webpack");
    const { merge } = require("webpack-merge");
    
    const common = require("./webpack.config.common.js");
    
    module.exports = merge(common, {
      mode: "development",
      output: {
        path: path.resolve(__dirname, "dist"),
        filename: "[name]-[hash:6].js",
        publicPath: config.publicPath,
        chunkFilename: "[name].[chunkhash:4].chunk.js",
      },
      devServer: {
        port: 8089,
        host: "0.0.0.0",
        hot: true, // css 修改热更新,js 热更新需要配合 hotOnly和webpack.HotModuleReplacementPlugin()
        compress: true,
        // 当使用 HTML5 History API 时, 所有的 404 请求都会响应 index.html 的内容。 将 devServer.historyApiFallback 设为 true开启:
        historyApiFallback: true, 
        hotOnly: true, // 即便HMR不⽣效,浏览器也不⾃动刷新,就开启hotOnly
        /* proxy: {   // 每个 key 都是需要转发的前缀
          "/dataassets/api": {
            target: "后端接口服务地址",
          },
        }, */
        proxy: [
          // 多个前缀代理到同一个后端服务写法
          {
            context: ["/dataassets/api", "/sso"],
            target: "后端接口服务地址",
          },
        ]
      },
      devtool: "inline-source-map", // 开发环境配置
      module: {
        rules: [
          {
            test: /\.(less|css)$/,
            use: [
              "style-loader",
              "css-loader",
              {
                loader: "less-loader",
                options: {
                  // less@3
                  javascriptEnabled: true,
                  // 覆盖antd样式的全局变量
                  modifyVars: config.modifyVars,
                  globalVars: {
                    imgUri: `~"${config.publicPath}"`,
                  },
                },
              },
            ],
          },
          {
            test: /\.(jpe?g|png|gif|svg)$/i,
            use: [
              "file-loader?hash=sha512&digest=hex&name=[hash].[ext]",
            ],
          },
          {
            test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
            use: "url-loader?limit=10000&mimetype=application/font-woff",
          },
          {
            test: /\.(ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
            use: "file-loader",
          },
        ],
      },
      plugins: [new webpack.HotModuleReplacementPlugin()],
    });
    

    webpack.config.production.js

    const path = require("path");
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    const CopyWebpackPlugin = require("copy-webpack-plugin");
    const { merge } = require("webpack-merge");
    const config = require("./config");
    const common = require("./webpack.config.common.js");
    
    module.exports = merge(common, {
      mode: "production",
      output: {
        path: path.resolve(__dirname, "../dist"),
        publicPath: config.publicPath, // 项目打包后的 css,js 都会添加统一访问路径前缀
        filename: "js/[name].[hash:6].js",
        chunkFilename: "js/[name].[hash:6].chunk.js",
      },
      module: {
        rules: [
          {
            test: /\.(less|css)$/,
            use: [
              {
                // MiniCssExtractPlugin 既有插件的配置也有 loader 的配置,具体配置项参考 github 文档
                // https://github.com/webpack-contrib/mini-css-extract-plugin
                loader: MiniCssExtractPlugin.loader,
                options: {
                  publicPath: config.publicPath, // 配置打包后访问 css 文件的路径前缀。
                },
              },
              "css-loader",
              "postcss-loader",
              {
                loader: "less-loader",
                options: {
                  // less@3
                  javascriptEnabled: true,
                  // 覆盖antd样式的全局变量
                  modifyVars: config.modifyVars,
                  globalVars: {
                    imgUri: `~"${config.publicPath}"`, // 用于设置样式文件里引入的 image 图片地址前缀
                  },
                },
              },
            ],
          },
          {
            test: /\.(jpe?g|png|gif|svg)$/i,
            use: [
              {
                loader: 'file-loader',
                options: {
                  name: "[name]-[contenthash:6].[ext]",
                  limit: 2 * 1024, // 小于2k的图片,直接使用Base64编码进行处理
                  publicPath: config.publicPath
                }
              }
            ],
          },
          {
            test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
            use: [
              {
                loader: 'url-loader',
                options: {
                  publicPath: config.publicPath
                }
              }
            ]
          },
          {
            test: /\.(ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
            use: [
              {
                loader: 'file-loader',
                options: {
                  publicPath: config.publicPath
                }
              }
            ]
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: "css/[contenthash:6]-[name].css",
        }),
        new CopyWebpackPlugin([
          {
            from: path.resolve(__dirname, "../static"),
            to: path.resolve(__dirname, "../dist/static"),
          },
        ]),
      ],
    });
    

    起源地下载网 » react + webpack 项目搭建

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元