webpack--基于vue-cli搭建一个多项目使用的工程

2,180 阅读4分钟

这个博文内容是基于vue-cli搭建一个多项目使用的工程(webpack版本3x), 可以让多个项目用同一个组件。实现一个工程对特定的项目运行开发环境和打包环境

纯小白教程,如果你和我一样都不懂webpack,那就进来吧

推荐文章

不懂webpack推荐看这个浅入浅出webpack(很短的,不多内容,但是可以有基本的了解),看完了再继续看下面的。

目录

项目改造后的结构如下

.babelrc
node_modules
package.json
...
components
项目1 (VUE Admin)
    dist
    src
        components
        page
        router
        main.js
        ...
    static
    index.html
项目2(React PC)
    dist
    src
        components
        page
        router
        main.txs
        ...
    static
    index.html
    tsconfig.json

入口

package.json 既然我们用了多项目,那么打包和开发一定会和之前不一样,命令肯定会加一个项目指定,修改package.json,找到scripts

把dev和build改成如下格式(admin是项目名字,根据自己的业务处理哦)

"admin-dev": "node build/dev-server.js admin",
"admin-build": "node build/build.js admin",

开发环境设置

可以看到我们执行admin-dev的时候,会执行node build/dev-server.js admin

在修改执行的时候,后面加了一个参数,这个参数我们需要解析,nodejs解析的话,就是用process.argv(详细介绍), 我们先获取那个参数, 然后保存到config/index.js里面,之后要用到

config/index.js

var projects_root_dir = process.argv[2]

修改build

index: path.resolve(__dirname, `../${projects_root_dir}/dist/index.html`),
assetsRoot: path.resolve(__dirname, `../${projects_root_dir}/dist`),

修改dev

assetsPublicPath: '/', 

dev-server.js

然后打开dev-server.js看看里面都是怎么玩的,顺便修改一下

// ...
// 上面代码省略, 只看这部分核心和要改的代码
// ...
// 这个就是页面输出到开发环境的东西
var devMiddleware = require("webpack-dev-middleware")(compiler, {
    // 这个删掉
    // publicPath: webpackConfig.output.publicPath,
    // 改成这个
    publicPath: '/',
    quiet: true,
})
// 这个是代理static静态文件的,用的是express框架
app.use(staticPath, express.static(`./${config.projects_root_dir}/static`));

要了解更多,点击进入webpack-dev-middleware的传送门

webpack.base.conf.js

修改entry

// 这个是入口文件,也就是执行nodejs代码后决定要从哪里入手编译,我们在前面添加一个config.projects_root_dir,这个就是nodejs后面的参数
entry: {
        app: `./${config.projects_root_dir}/src/main.js`
},

修改resolve函数

// 这个函数在alias里面会用到,也就是import的时候,前面加的那个东西。

// 删掉这个
// return path.join(__dirname, dir)
// 替换成
var resolve_path = path.join(
        __dirname,
        "../" + config.projects_root_dir,
        dir
);

修改rules

// 在test: /\.vue$/,这里添加一个
// include: [path.join(__dirname, '../')]
// 如下
{
        test: /\.vue$/,
        loader: "vue-loader",
        options: vueLoaderConfig,
        include: [path.join(__dirname, '../')]
}
// 这个include不要改成resolve("src"),因为公共项目,其他地方也需要编译的

build/utils.js

这里文件里面可能会有less等需要编译,我们找到resources,然后在path.resolve这个函数第二个位置添加'../' + config.projects_root_dir 如下

 resources: [path.resolve(__dirname, '../' + config.projects_root_dir, config.less_resources)]

到这里的话开发环境就搭建好了。 npm run admin-dev就可以运行起来了。(如果没有意外的话)。

效果

完美运行

打包环境设置

webpack.prod.conf.js

HtmlWebpackPlugin修改下面代码

// 修改成如下,这个地方是决定把html文件弄到哪里去
template: `${config.projects_root_dir}/index.html`,

CopyWebpackPlugin修改如下

// 这个是决定从哪里开始复制文件,to不需要改变(如果业务需要那就改变)
from: path.resolve(__dirname, `../${config.projects_root_dir}/static`),

完美打包

然后用nginx代理本地测试下(完美跑起来)

配置别名,引用项目外的组件

// .. 前后代码不展示哈
function private_resolve() {
    var privete_page_resolve_path = path.join(__dirname, "../components", "");
    return privete_page_resolve_path;
}
// .. 前后代码不展示哈
module.exports = {
    // .. 前后代码不展示哈
    alias: {
        "@": resolve("src"),
        "p~": private_resolve()
    }
}

然后所有项目都可以引入啦。

import test 'p~/test'

其他

如果怕麻烦,也可以npm link创建软链接。
然后配合私有npm,使用verdaccio搭建私有npm,传送门

加一个React项目

上面建立了一个叫admin的项目。我们现在在旁边加一个react(使用tsx)的项目。 名字,我们取叫PC

package.json脚本里面添加如下属性

"pc-dev": "node build/dev-server.js pc 3035 main.tsx",
"pc-build": "node build/build.js pc",

发现对比之前的,我们后面加了3035端口和main.tsx。这是因为端口一致的话会无法启动多个项目,于是自定义端口。而main.tsx是因为启动的入口发生了变化, 因为我们React项目用main.js作为入口不太合适了。

修改config/index.js

// ---设置端口和入口---

// 设置默认值
const default_port = 7080
const default_main_filename = 'main.js'

var projects_root_dir = process.argv[2]
var projects_port = process.argv[3] || default_port
var projects_main_filename = process.argv[4] || default_main_filename

// --- 然后修改下面两个地方
module.exports = {
    projects_root_dir,
    // 新增
    projects_main_filename,
    ...CODE
    dev: {
        ... CODE
        // 修改
        port: projects_port,
        ... CODE
    }
    ...CODE
}

属性设置好了,修改入口和添加扩展名(可以不加,但是建议),和tsx(如果不用ts就加jsx)。 打开webpack.base.conf.js修改即可

...
// 修改入口
entry: {
    app: `./${config.projects_root_dir}/src/${config.projects_main_filename}`
}
...
// 添加扩展
extensions: [".js", ".vue", ".json", ".jsx", '.ts' , '.tsx']
...
// 添加tsx的解析
// 需要在前面加const tsImportPluginFactory = require('ts-import-plugin') 引入哦。 
// npm run install ts-import-plugin --save-dev
{
    test: /\.tsx?$/,
    loader: 'ts-loader',
    options: {
        transpileOnly: true,
        getCustomTransformers: () => ({
          before: [ tsImportPluginFactory( /** options */) ]
        }),
        compilerOptions: {
          module: 'es2015'
        }
    },
    exclude: /node_modules/,
    include: [resolve("src"), private_resolve()]
},
...

完成就可以新建pc目录,然后里面添加一个index.html,index.html加一个带id的div。 和新建一个tsconfig.json, 这个可以参考我一个的项目的tsconfig.json, 点击查看

然后新建一个src, 里面加一个main.tsx写代码就可以啦。(如下图)

Ract代码可以参考点击查看

关于React和vue互相调用组件

vuera

更多

好像也可以统一根据目录生成路由,不过会有局限性。代码路由和目录路由保持一致是最好啦,这样团队别人的代码也不用先去router表看一下,然后再定位过去。

--完--