彼岸曼陀罗

彼岸曼陀罗 查看完整档案

深圳编辑  |  填写毕业院校  |  填写所在公司/组织 vvv.com 编辑
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

彼岸曼陀罗 收藏了文章 · 2020-06-22

React 项目如何修改打包地址(编译输出文件地址)

好吧,笔者是一个后端开发。以前是做C/S项目出身,毫无Web前端基础,为了更好地理解Web开发,去年开始尝试使用公司使用的前端框架React来搭建团队内部使用的系统。通过这个项目的开发,也让我更好地理解了前端同事的不容易,更加坚定了写好接口文档的决心。

最近在把自己做的这个内部系统迁移到公司的统一平台的时候,遇到了一个小问题,公司要求打包的目录名必须为dist,而我这个项目是使用create-react-app搭建的,所以打包的目录是默认的build

遂开始了查找如何修改打包目录的资料。随便在网上一搜,便是如下的解决方案:

使用eject命令暴露配置,然后修改打包地址

使用这个命令,是不可逆的,执行之前,请将代码备份或提交版本库

1、使用eject命令暴露配置:

npm run eject

2、修改暴露出的配置文件config/path.js,将appBuild修改为需要输出的位置。

3、使用npm install命令安装依赖,然后执行npm run build打包

这个方案当然一点毛病都没有,通过这个可以认识到,create-react-app在创建React项目的时候,是隐藏了许多开发者不需要过多关心的配置项的,尽量简化了前端的开发。而eject命令则可以让这些配置项暴露出来。

eject的弊端

要注意的是,eject命令是不可逆的(至少官方没有提供回退的方法)。使用了这个命令,你就要接受你的开发目录面多了很多的配置文件和脚本。

这还不是最关键的,因为我的项目使用了antd作为UI框架,其使用了react-app-rewired这个东东,导致我在eject之后执行npm run build会报错。

react-app-rewired是什么?

作为一个后端开发,最大的感触就是,前端的网上资料有用的太少,因为各种框架、技术更新迭代太快,很多博客上的解决方案都已经过时了。你们看到的我的这篇文章,可能很快也会过时,但是我会把思路教给大家——话说,当遇到一个技术问题,实在解决不了怎么办?当然是找官方文档了

通过在react-app-rewired官方文档,才知道这个工具的一个功能是在不eject的情况下,修改配置文件。上文说到的antd也是为了实现修改配置,才引入的这个工具。既然它的功能如此,那么用来修改打包地址应该也是可行的。

使用react-app-rewired在不eject的情况下修改打包地址

思路虽然有了,但是对于前端基础薄弱的后台开发来说,还是不知道怎么实操,在看了几篇issue之后,Changing the default pathsChange build output path之后,终于找到了方法。

首先当然是要引入react-app-rewired了,这里我就不写方法了,大家参考官方文档,不会过时。

引入之后,会有一个config-overrides.js文件,因为我引入了antd,里面已经有了些内容:

// 此文件是为了ant选择性引入
const {injectBabelPlugin} = require('react-app-rewired');

module.exports = function override(config, env) {
    // antd选择性引入
    config = injectBabelPlugin(['import', {libraryName: 'antd', libraryDirectory: 'es', style: 'css'}], config);
    return config;
};

增加如下代码(去掉我用来标记代码的+号哈):

// 此文件是为了ant选择性引入
const {injectBabelPlugin} = require('react-app-rewired');

module.exports = function override(config, env) {
    // antd选择性引入
    config = injectBabelPlugin(['import', {libraryName: 'antd', libraryDirectory: 'es', style: 'css'}], config);

+   // 修改path目录
+   const path = require('path');
+   const paths = require('react-scripts/config/paths');
+   paths.appBuild = path.join(path.dirname(paths.appBuild), 'dist');
+   config.output.path = path.join(path.dirname(config.output.path), 'dist');

    return config;
};

如此,再执行npm run build就可以了,问题解决。

如果你已经进行了eject操作,很遗憾,只能通过版本库回退版本了。

修复npm run start失败的问题

做了以上的修改之后,会导致npm run start失败,错误提示:

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined

根据提示语分析得知应该是在npm run start模式下启动时,path获取有问题,方法function override(config, env)里有个env参数,最简单粗暴的方式——根据此参数判断用户时是启动的development还是production进而进行不同的处理。

按下面的方式修改代码即可。

// 此文件是为了ant选择性引入
const {injectBabelPlugin} = require('react-app-rewired');

// noinspection JSUnusedLocalSymbols
module.exports = function override(config, env) {
    // antd选择性引入
    config = injectBabelPlugin(['import', {libraryName: 'antd', libraryDirectory: 'es', style: 'css'}], config);

+   if(env === 'development'){
+       console.log('evn is development, skip build path change...')
+   } else if(env === 'production') {
+       console.log('evn is production, change build path...')
        // 修改path目录
        const path = require('path');
        const paths = require('react-scripts/config/paths');
        paths.appBuild = path.join(path.dirname(paths.appBuild), 'dist');
        config.output.path = path.join(path.dirname(config.output.path), 'dist');
+   }
    return config;
};

尾声:配置代码解析

到了这里,估计有部分同学还不满意为什么以上代码能够解决问题,作为一个外行人,我按我的理解解释下。

const path = require('path');

这行代码是基于require.js,是一个js进行引入包的工具。通过这行代码,拿到path,才能够对路径做处理。

const paths = require('react-scripts/config/paths');

react-scripts里面有React项目用于打包的命令,以及配置文件,如果你进行了eject,会发现config和script目录里的内容与react-scripts里的同名目录惊人的相似。可以认为eject是把这里的配置暴露出来了。这里这行代码是为了获取项目的路径配置。

paths.appBuild = path.join(path.dirname(paths.appBuild), 'dist');

这行代码是修改配置里的appBuild目录,React项目在进行build的时候,都是根据这里配置的目录做的操作(例如检查打包后的代码大小,计算Gzip等),必须要修改,不然打包会失败。

config.output.path = path.join(path.dirname(config.output.path), 'dist');

这行代码就是实现我们目的的根源了,修改项目打包地址。

好了,到这里本文结束。

尾声:福利

如果本文对你有帮助,欢迎关注、点赞、收藏一波。

最近业余时间做了个Java+React爬虫项目,感兴趣的朋友Star一波:https://github.com/hxy91819/c...,内有福利哦!

查看原文

彼岸曼陀罗 赞了文章 · 2020-06-22

React 项目如何修改打包地址(编译输出文件地址)

好吧,笔者是一个后端开发。以前是做C/S项目出身,毫无Web前端基础,为了更好地理解Web开发,去年开始尝试使用公司使用的前端框架React来搭建团队内部使用的系统。通过这个项目的开发,也让我更好地理解了前端同事的不容易,更加坚定了写好接口文档的决心。

最近在把自己做的这个内部系统迁移到公司的统一平台的时候,遇到了一个小问题,公司要求打包的目录名必须为dist,而我这个项目是使用create-react-app搭建的,所以打包的目录是默认的build

遂开始了查找如何修改打包目录的资料。随便在网上一搜,便是如下的解决方案:

使用eject命令暴露配置,然后修改打包地址

使用这个命令,是不可逆的,执行之前,请将代码备份或提交版本库

1、使用eject命令暴露配置:

npm run eject

2、修改暴露出的配置文件config/path.js,将appBuild修改为需要输出的位置。

3、使用npm install命令安装依赖,然后执行npm run build打包

这个方案当然一点毛病都没有,通过这个可以认识到,create-react-app在创建React项目的时候,是隐藏了许多开发者不需要过多关心的配置项的,尽量简化了前端的开发。而eject命令则可以让这些配置项暴露出来。

eject的弊端

要注意的是,eject命令是不可逆的(至少官方没有提供回退的方法)。使用了这个命令,你就要接受你的开发目录面多了很多的配置文件和脚本。

这还不是最关键的,因为我的项目使用了antd作为UI框架,其使用了react-app-rewired这个东东,导致我在eject之后执行npm run build会报错。

react-app-rewired是什么?

作为一个后端开发,最大的感触就是,前端的网上资料有用的太少,因为各种框架、技术更新迭代太快,很多博客上的解决方案都已经过时了。你们看到的我的这篇文章,可能很快也会过时,但是我会把思路教给大家——话说,当遇到一个技术问题,实在解决不了怎么办?当然是找官方文档了

通过在react-app-rewired官方文档,才知道这个工具的一个功能是在不eject的情况下,修改配置文件。上文说到的antd也是为了实现修改配置,才引入的这个工具。既然它的功能如此,那么用来修改打包地址应该也是可行的。

使用react-app-rewired在不eject的情况下修改打包地址

思路虽然有了,但是对于前端基础薄弱的后台开发来说,还是不知道怎么实操,在看了几篇issue之后,Changing the default pathsChange build output path之后,终于找到了方法。

首先当然是要引入react-app-rewired了,这里我就不写方法了,大家参考官方文档,不会过时。

引入之后,会有一个config-overrides.js文件,因为我引入了antd,里面已经有了些内容:

// 此文件是为了ant选择性引入
const {injectBabelPlugin} = require('react-app-rewired');

module.exports = function override(config, env) {
    // antd选择性引入
    config = injectBabelPlugin(['import', {libraryName: 'antd', libraryDirectory: 'es', style: 'css'}], config);
    return config;
};

增加如下代码(去掉我用来标记代码的+号哈):

// 此文件是为了ant选择性引入
const {injectBabelPlugin} = require('react-app-rewired');

module.exports = function override(config, env) {
    // antd选择性引入
    config = injectBabelPlugin(['import', {libraryName: 'antd', libraryDirectory: 'es', style: 'css'}], config);

+   // 修改path目录
+   const path = require('path');
+   const paths = require('react-scripts/config/paths');
+   paths.appBuild = path.join(path.dirname(paths.appBuild), 'dist');
+   config.output.path = path.join(path.dirname(config.output.path), 'dist');

    return config;
};

如此,再执行npm run build就可以了,问题解决。

如果你已经进行了eject操作,很遗憾,只能通过版本库回退版本了。

修复npm run start失败的问题

做了以上的修改之后,会导致npm run start失败,错误提示:

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined

根据提示语分析得知应该是在npm run start模式下启动时,path获取有问题,方法function override(config, env)里有个env参数,最简单粗暴的方式——根据此参数判断用户时是启动的development还是production进而进行不同的处理。

按下面的方式修改代码即可。

// 此文件是为了ant选择性引入
const {injectBabelPlugin} = require('react-app-rewired');

// noinspection JSUnusedLocalSymbols
module.exports = function override(config, env) {
    // antd选择性引入
    config = injectBabelPlugin(['import', {libraryName: 'antd', libraryDirectory: 'es', style: 'css'}], config);

+   if(env === 'development'){
+       console.log('evn is development, skip build path change...')
+   } else if(env === 'production') {
+       console.log('evn is production, change build path...')
        // 修改path目录
        const path = require('path');
        const paths = require('react-scripts/config/paths');
        paths.appBuild = path.join(path.dirname(paths.appBuild), 'dist');
        config.output.path = path.join(path.dirname(config.output.path), 'dist');
+   }
    return config;
};

尾声:配置代码解析

到了这里,估计有部分同学还不满意为什么以上代码能够解决问题,作为一个外行人,我按我的理解解释下。

const path = require('path');

这行代码是基于require.js,是一个js进行引入包的工具。通过这行代码,拿到path,才能够对路径做处理。

const paths = require('react-scripts/config/paths');

react-scripts里面有React项目用于打包的命令,以及配置文件,如果你进行了eject,会发现config和script目录里的内容与react-scripts里的同名目录惊人的相似。可以认为eject是把这里的配置暴露出来了。这里这行代码是为了获取项目的路径配置。

paths.appBuild = path.join(path.dirname(paths.appBuild), 'dist');

这行代码是修改配置里的appBuild目录,React项目在进行build的时候,都是根据这里配置的目录做的操作(例如检查打包后的代码大小,计算Gzip等),必须要修改,不然打包会失败。

config.output.path = path.join(path.dirname(config.output.path), 'dist');

这行代码就是实现我们目的的根源了,修改项目打包地址。

好了,到这里本文结束。

尾声:福利

如果本文对你有帮助,欢迎关注、点赞、收藏一波。

最近业余时间做了个Java+React爬虫项目,感兴趣的朋友Star一波:https://github.com/hxy91819/c...,内有福利哦!

查看原文

赞 5 收藏 3 评论 0

彼岸曼陀罗 提出了问题 · 2020-02-25

react项目中使用@antv/g6,运行正常,在build打包时报错

create-react-app项目中使用@antv/g6可视化引擎,版本如下:
`"@antv/g6": "3.2.8",
"react": "16.7.0",
"react-dom": "^16.4.1",
"babel-core": "6.26.0",
"babel-eslint": "7.2.3",
"babel-jest": "20.0.3",
"babel-loader": "7.1.2",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-react-app": "3.1.1",
"babel-runtime": "6.26.0",`

在执行yarn build命令打包时报如下错误:
`Failed to minify the code from this file:

    ./node_modules/@antv/g6/build/g6.js:9:97840

Read more here: http://bit.ly/2tRViJ9
`
@antv/g6的版本从3.1.X往上走都是报一样的错误,请教各位大神有没有遇到过一样的问题?该如何解决?

关注 1 回答 1

彼岸曼陀罗 赞了回答 · 2020-02-24

React通过Link路由跳转页面,加上 target="_blank"后,参数失效

这个确实取不到。不知道 React-Router 为什么这么设计。

你可以通过自己的方式来解析 url 后面的 query 参数。

关注 1 回答 1

彼岸曼陀罗 提出了问题 · 2020-02-24

React通过Link路由跳转页面,加上 target="_blank"后,参数失效

React项目通过Link跳转路由,想要在新窗口打开详情页,因此在Link上添加target="_blank",如下:
<Link to={{pathname:"/page/service/repair/detail", query:{initForm: row}}} target="_blank">明细表详情</Link>

新页面通过this.props.location.query.initForm获取参数,但是加上target="_blank"后,参数就获取不到了,请教各位大神如何解决?

关注 1 回答 1

彼岸曼陀罗 提出了问题 · 2020-02-24

React通过Link路由跳转页面,刷新后页面参数消失

React项目通过Link跳转路由:
<Link to\={{pathname:"/page/service/repair/detail", query:{initForm: row}}}>明细表详情</Link\>

新页面通过this.props.location.query.initForm获取参数

跳转成功,参数也传过去了,但是再刷新页面时,query参数就获取不到了,请教各位大神有没有什么好的解决办法?

关注 2 回答 1

彼岸曼陀罗 回答了问题 · 2018-01-10

解决vue项目用微信打开被腾讯公益404页面拦截了

请教大神,终于解决了这个问题,分享一下解决方案:
因为我用的是阿里云的虚拟主机,本以为是在基础环境设置里面设置404页面的指向地址就可以了

clipboard.png

但实际上是没有用的,还需要在与index.html同级的根目录使用.htaccess文件来配置url重定向,将所有路由都重定向到index.html,在.htaccess文件中添加代码如下:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

关注 4 回答 4

彼岸曼陀罗 提出了问题 · 2018-01-09

解决vue项目用微信打开被腾讯公益404页面拦截了

用vue-cli做的一个项目,用vue-router实现路由,打包后部署在阿里云服务器上,在阿里云服务器设置了404页面指向到index.html,这样就保证了直接访问路由地址不会报404的问题。
比如直接访问http://tangmai.com.cn/about/top 他就会直接通过路由跳转到指定的页面。


但是现在问题来了,有一些手机通过微信去访问这个地址:http://tangmai.com.cn/about/top 他会出现腾讯公益的404页面,而不是按照预期的服务器找不到虚拟路径就跳转到index.html,然后再通过前端的路由跳转页面。
分析了很久这个问题的原因,应该是腾讯将我的404给拦截了,强制转向到腾讯公益的404页面。

clipboard.png

虽然找到原因了,但还是没有解决办法,如果不想被强制跳转到腾讯公益的404页面该怎么做?
希望各位前端大神们帮帮忙

关注 4 回答 4

彼岸曼陀罗 提出了问题 · 2017-11-24

webpack-dev-server页面刷新了,但内容却没用变

用webpack写一个小例子,webpack.config.js配置如下:

var webpack = require('webpack');
    var path = require('path');
    
    module.exports = {
        entry:  __dirname + "/src/js/index.js",  //入口文件
        module:{
            loaders:[{
                test: /\.js?$/,  //正则解析所有js文件
                exclude: /(node_modules)/,   //不包含的文件夹
                loader: 'babel-loader',  //用babel-loader来解析
                query:{
                    presets:['react','es2015']   //加载包
                }
            }]
        },
        output:{    //输出文件
            path: __dirname + '/dist/js',
            filename: "bundle.js"
        }
    }

通过webpack-dev-server启动后,修改代码可以看到页面刷新了,但是内容却没用变化:

clipboard.png

求大神指教,是我的配置没用写好,还是其他原因呢?

关注 3 回答 2

彼岸曼陀罗 赞了回答 · 2017-08-04

解决vue如何让自定义函数挂到全局

// xxx.js 组件
exports.install = function (Vue, options) {
    Vue.prototype.ajax = function (){
        alert('aaaaaaa');
    };
};
// main.js 入口
import xxxx from './commons/xxxx'
Vue.use(xxxx);
// ccc.js 子组件
this.ajax();

关注 8 回答 4

认证与成就

  • 获得 3 次点赞
  • 获得 16 枚徽章 获得 2 枚金徽章, 获得 3 枚银徽章, 获得 11 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2016-03-29
个人主页被 435 人浏览