Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Taro 3] Webpack 建议使用 resolve.extensions 替换 MultiPlatformPlugin #6786

Closed
fjc0k opened this issue Jun 24, 2020 · 11 comments
Closed
Assignees
Labels
A-cli Area - CLI 相关 enhancement New feature or request V-3 Version - 3.x
Milestone

Comments

@fjc0k
Copy link
Contributor

fjc0k commented Jun 24, 2020

问题描述

目前 Taro 使用 MultiPlatformPlugin 支持多平台后缀,但 MultiPlatformPlugin 里不遵从原有的 resolve.extensions,导致 resolve.extensions 实质上是形同虚设的。

因此,建议直接使用 resolve.extensions 支持多平台,将 resolve 的事情交与 Webpack,减少不必要的麻烦。

这是我在本地对 mini-runner/dist/webpack/base.conf.js 的修改,运行正常:

exports.default = (appPath) => {
    const platform = process.env.TARO_ENV;
    const baseExts = ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.vue'];
    const taroExts = baseExts.map(ext => `.taro${ext}`);
    const platformExts = [...taroExts, ...baseExts].map(ext => `.${platform}${ext}`);
    const resolveExts = [...platformExts, ...taroExts, ...baseExts];
    const chain = new Chain();
    chain.merge({
        resolve: {
            extensions: resolveExts,

微信小程序开发时,resolveExts 为:

[
  '.weapp.taro.js',  '.weapp.taro.jsx',
  '.weapp.taro.ts',  '.weapp.taro.tsx',
  '.weapp.taro.mjs', '.weapp.taro.vue',
  '.weapp.js',       '.weapp.jsx',
  '.weapp.ts',       '.weapp.tsx',
  '.weapp.mjs',      '.weapp.vue',
  '.taro.js',        '.taro.jsx',
  '.taro.ts',        '.taro.tsx',
  '.taro.mjs',       '.taro.vue',
  '.js',             '.jsx',
  '.ts',             '.tsx',
  '.mjs',            '.vue'
]

另外,建议默认支持 .taro.[js|jsx|ts|tsx|...] 后缀,这对于通用工具库的开发是十分友好的,比如我要开发一个 useTitle 动态设置标题的 React Hook:

// useTitle.js
import { useEffect } from 'react'

export function useTitle(title) {
  useEffect(() => {
     document.title = title
  }, [title])
}
// useTitle.taro.js
import { useEffect } from 'react'
import { setNavigationBarTitle } from '@tarojs/taro';

export function useTitle(title) {
  useEffect(() => {
     setNavigationBarTitle({ title: title })
  }, [title])
}

如上,就是一个同时支持其他任意开发工具和 Taro 的 useTitle

@fjc0k
Copy link
Contributor Author

fjc0k commented Jun 24, 2020

在官方未支持的情况下,项目中可这样支持 .taro.js 后缀:

// config/index.js
mini: {
    webpackChain(config) {
        // 该插件会影响 resolve.extensions 的表现,删除
        config.resolve.plugins.delete('MultiPlatformPlugin')
        // 支持 .taro.js 后缀,不再支持多平台后缀
        config.resolve.extensions.prepend('.taro.js')
    },
}

@luckyadam
Copy link
Member

MultiPlatformPlugin 这个插件主要解决的问题是,支持跨平台文件

@fjc0k
Copy link
Contributor Author

fjc0k commented Jun 29, 2020

@luckyadam 看了源码,没必要啊,webpack 原生就行,干嘛搞个插件,而且这个插件还把 webpack 的 resolve.extensions 给搞失效了,本来用 resolve.extensions 实现跨平台文件就行了。

@luckyadam
Copy link
Member

@luckyadam 看了源码,没必要啊,webpack 原生就行,干嘛搞个插件,而且这个插件还把 webpack 的 resolve.extensions 给搞失效了,本来用 resolve.extensions 实现跨平台文件就行了。

用 resolver 的插件来实现这个需求是比较合理的

@fjc0k
Copy link
Contributor Author

fjc0k commented Jun 30, 2020

@luckyadam 本质就是个后缀的问题嘛,怎样实现我倒觉得没啥,就是现在它不遵循 resolve.extensions 定义的后缀,只会找 js,jsx,ts,tsx,而且导致 resolve.extensions 失效,那 resolve.extensions 里的 mjs, cjs, vue, taro.js 有啥用呢

@Chen-jj Chen-jj added enhancement New feature or request V-3 Version - 3.x and removed CLI labels Jul 10, 2020
@Chen-jj Chen-jj added this to the 3.1.0 milestone Jul 30, 2020
@Chen-jj Chen-jj added the A-cli Area - CLI 相关 label Jul 30, 2020
@wangking873
Copy link

跨平台不是应该用 mainFields吗?

"main": "lib/index.js", 目标环境 node.js
"browser": "es/index.js", 目标环境 浏览器
"taromini": "mini/index.js", 目标环境 taro小程序

@Chen-jj
Copy link
Contributor

Chen-jj commented Oct 29, 2020

多端文件的解析需要遵循 extensions 配置的问题在 3.1 修复。

taro 后缀暂时不实现了,像楼上所说,用 mainFields 应该就能解决。

跨平台不是应该用 mainFields吗?

@wangking873
Copy link

wangking873 commented Nov 4, 2020

mainFields: ['main:h5', 'browser', 'module', 'main'],

mainFields: ['browser', 'module', 'main'],

mainFields: ['module', 'js-next', 'main']

我在taro的源码里找到三个mainFields定义,如果我自定义的库 需要同时支持 node(ssr) browser(browser-webpack) taromini(taro-webpack) 三个平台

我需要分别自己定义mainFields吗? taro能提供一个默认推荐吗?

建议
1.H5 webpack配置 mainFields: ['browser', 'module', 'main']

2.小程序 webpack配置 mainFields: ['taromini', 'module', 'main']

@tarojs/components 组件库 package.json 可以做个最佳参考, 现在是

"main:h5": "src/index.js",
"main": "dist/index.js",
"module": "dist/index.mjs",

#3415

@fjc0k
Copy link
Contributor Author

fjc0k commented Nov 4, 2020

我也觉得 Taro 应该增加 mainFields 作为多端适配的能力,比如:

[`taro:${process.env.TARO_ENV}`, 'taro']

@Chen-jj
Copy link
Contributor

Chen-jj commented Nov 4, 2020

Taro H5 入口 main:h5
Taro Mini 入口 main:mini

项目修改 webpack 配置 mainFields: ['main:h5', 'main:mini', 'browser', 'module', 'main'],这样应该就可以了吧。

@wangking873
Copy link

wangking873 commented Nov 4, 2020

h5打包webpack
mainFields: ['main:h5', 'browser', 'module', 'main']

小程序打包webpack
mainFields: ['main:mini', 'browser', 'module', 'main']

因为一个库会有多种入口,打包时要指定优先级。

"main:h5": "h5/index.js",
"main:mini": "dist/index.js",
"browser": "es/index.js",
"module": "src/index.mjs",
"main": "lib/index.mjs",

This was referenced Feb 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-cli Area - CLI 相关 enhancement New feature or request V-3 Version - 3.x
Projects
None yet
Development

No branches or pull requests

4 participants