index.js 11.7 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2 3 4 5 6
const path = require('path')
const webpack = require('webpack')

const {
  parseEntry,
  getMainEntry,
7
  normalizePath,
fxy060608's avatar
fxy060608 已提交
8
  getPlatformExts,
fxy060608's avatar
fxy060608 已提交
9 10
  getPlatformCssnano,
  getPlatformStat,
雪洛's avatar
雪洛 已提交
11
  getPlatformPush,
fxy060608's avatar
fxy060608 已提交
12 13
  getPlatformUniCloud,
  uniModulesLoader
fxy060608's avatar
fxy060608 已提交
14 15
} = require('@dcloudio/uni-cli-shared')

fxy060608's avatar
fxy060608 已提交
16
const WebpackUniAppPlugin = require('../../packages/webpack-uni-app-loader/plugin/index')
fxy060608's avatar
fxy060608 已提交
17

fxy060608's avatar
fxy060608 已提交
18
const modifyVueLoader = require('../vue-loader')
fxy060608's avatar
fxy060608 已提交
19

fxy060608's avatar
fxy060608 已提交
20
const {
fxy060608's avatar
fxy060608 已提交
21
  createTemplateCacheLoader
fxy060608's avatar
fxy060608 已提交
22
} = require('../cache-loader')
fxy060608's avatar
fxy060608 已提交
23

fxy060608's avatar
fxy060608 已提交
24
function createUniMPPlugin () {
25
  const WebpackUniMPPlugin = require('@dcloudio/webpack-uni-mp-loader/lib/plugin/index-new')
fxy060608's avatar
fxy060608 已提交
26 27 28
  return new WebpackUniMPPlugin()
}

S
songyu 已提交
29
const createWxMpIndependentPlugins = require('@dcloudio/uni-mp-weixin/lib/createIndependentPlugin')
d-u-a's avatar
d-u-a 已提交
30 31

const UniTips = require('./tips')
32

fxy060608's avatar
fxy060608 已提交
33
function getProvides () {
fxy060608's avatar
fxy060608 已提交
34
  const uniPath = require('@dcloudio/uni-cli-shared/lib/platform').getMPRuntimePath()
fxy060608's avatar
fxy060608 已提交
35
  const uniCloudPath = path.resolve(__dirname, '../../packages/uni-cloud/dist/index.js')
fxy060608's avatar
fxy060608 已提交
36
  const provides = {
fxy060608's avatar
fxy060608 已提交
37 38
    uni: [uniPath, 'default'],
    uniCloud: [uniCloudPath, 'default']
fxy060608's avatar
fxy060608 已提交
39 40
  }

fxy060608's avatar
fxy060608 已提交
41 42 43 44 45
  if (process.env.UNI_USING_VUE3) {
    provides.uni = ['@dcloudio/uni-' + process.env.UNI_PLATFORM + '/dist/uni.api.esm.js', 'default']
    provides.createMiniProgramApp = [uniPath, 'createApp']
  }

fxy060608's avatar
fxy060608 已提交
46
  if (process.env.UNI_USING_COMPONENTS) {
fxy060608's avatar
fxy060608 已提交
47 48
    if (process.env.UNI_SUBPACKGE) {
      provides.createApp = [uniPath, 'createSubpackageApp']
49 50
    } else if (process.env.UNI_MP_PLUGIN) {
      provides.createApp = [uniPath, 'createPlugin']
fxy060608's avatar
fxy060608 已提交
51 52 53
    } else {
      provides.createApp = [uniPath, 'createApp']
    }
fxy060608's avatar
fxy060608 已提交
54 55
    provides.createPage = [uniPath, 'createPage']
    provides.createComponent = [uniPath, 'createComponent']
fxy060608's avatar
fxy060608 已提交
56 57 58 59 60 61
  }

  if (
    process.env.UNI_PLATFORM === 'app-plus' &&
    process.env.UNI_USING_V8
  ) {
fxy060608's avatar
fxy060608 已提交
62
    provides.__f__ = [path.resolve(__dirname, '../format-log.js'), 'default']
63

fxy060608's avatar
fxy060608 已提交
64
    const cryptoProvide = [path.resolve(__dirname, '../crypto.js'), 'default']
fxy060608's avatar
fxy060608 已提交
65
    provides.crypto = cryptoProvide
66 67
    provides['window.crypto'] = cryptoProvide
    provides['global.crypto'] = cryptoProvide
fxy060608's avatar
fxy060608 已提交
68 69 70 71 72 73 74 75
  }

  // TODO 目前依赖库 megalo 通过判断 wx 对象是否存在来识别平台做不同处理
  if (
    process.env.UNI_PLATFORM !== 'mp-qq' &&
    process.env.UNI_PLATFORM !== 'mp-weixin' &&
    process.env.UNI_PLATFORM !== 'app-plus'
  ) { // 非微信小程序,自动注入 wx 对象
fxy060608's avatar
fxy060608 已提交
76
    provides.wx = provides.uni
fxy060608's avatar
fxy060608 已提交
77 78 79 80
  }
  return provides
}

fxy060608's avatar
fxy060608 已提交
81 82
function processWxss (name, assets) {
  const dirname = path.dirname(name)
83
  const mainWxssCode = `@import "${normalizePath(path.relative(dirname, 'common/main.wxss'))}";`
fxy060608's avatar
fxy060608 已提交
84 85 86 87 88 89 90 91 92 93 94
  const code = `${mainWxssCode}` + assets[name].source().toString()
  assets[name] = {
    size () {
      return Buffer.byteLength(code, 'utf8')
    },
    source () {
      return code
    }
  }
}

95 96
const parseRequirePath = path => path.startsWith('common') ? `./${path}` : path

fxy060608's avatar
fxy060608 已提交
97 98
function procssJs (name, assets, hasVendor) {
  const dirname = path.dirname(name)
99
  const runtimeJsCode = `require('${normalizePath(parseRequirePath(path.relative(dirname, 'common/runtime.js')))}');`
fxy060608's avatar
fxy060608 已提交
100 101
  const vendorJsCode = hasVendor
    ? `require('${normalizePath(parseRequirePath(path.relative(dirname, 'common/vendor.js')))}');` : ''
102
  const mainJsCode = `require('${normalizePath(parseRequirePath(path.relative(dirname, 'common/main.js')))}');`
fxy060608's avatar
fxy060608 已提交
103 104 105 106 107 108 109 110 111 112 113
  const code = `${runtimeJsCode}${vendorJsCode}${mainJsCode}` + assets[name].source().toString()
  assets[name] = {
    size () {
      return Buffer.byteLength(code, 'utf8')
    },
    source () {
      return code
    }
  }
}

fxy060608's avatar
fxy060608 已提交
114 115 116 117
class PreprocessAssetsPlugin {
  apply (compiler) {
    compiler.hooks.emit.tap('PreprocessAssetsPlugin', compilation => {
      const assets = compilation.assets
fxy060608's avatar
fxy060608 已提交
118
      const hasMainWxss = assets['common/main.wxss']
fxy060608's avatar
fxy060608 已提交
119 120 121 122 123
      const hasVendor = assets['common/vendor.js']
      Object.keys(assets).forEach(name => {
        if (name.startsWith('common')) {
          return
        }
fxy060608's avatar
fxy060608 已提交
124 125 126 127 128
        const extname = path.extname(name)
        if (extname === '.wxss' && hasMainWxss && process.UNI_ENTRY[name.replace(extname, '')]) {
          processWxss(name, assets)
        } else if (extname === '.js') {
          procssJs(name, assets, hasVendor)
fxy060608's avatar
fxy060608 已提交
129 130
        }
      })
fxy060608's avatar
fxy060608 已提交
131
      // delete assets['common/main.js']
fxy060608's avatar
fxy060608 已提交
132 133 134 135 136 137 138 139 140
      delete assets['app.js']
      delete assets['app.json']
      delete assets['app.wxss']
      delete assets['project.config.json']
    })
  }
}

function initSubpackageConfig (webpackConfig, vueOptions) {
141
  if (process.env.UNI_OUTPUT_DEFAULT_DIR === process.env.UNI_OUTPUT_DIR) { // 未自定义output
fxy060608's avatar
fxy060608 已提交
142 143
    process.env.UNI_OUTPUT_DIR = path.resolve(process.env.UNI_OUTPUT_DIR, (process.env.UNI_SUBPACKGE || process.env
      .UNI_MP_PLUGIN))
144
  }
fxy060608's avatar
fxy060608 已提交
145 146
  vueOptions.outputDir = process.env.UNI_OUTPUT_DIR
  webpackConfig.output.path(process.env.UNI_OUTPUT_DIR)
147
  webpackConfig.output.jsonpFunction('webpackJsonp_' + (process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN))
fxy060608's avatar
fxy060608 已提交
148 149
}

150 151 152 153
function addToUniEntry (fileName) {
  fileName && (process.UNI_ENTRY[fileName.split('.')[0]] = path.resolve(process.env.UNI_INPUT_DIR, fileName))
}

fxy060608's avatar
fxy060608 已提交
154 155 156 157
module.exports = {
  vueConfig: {
    parallel: false
  },
fxy060608's avatar
fxy060608 已提交
158
  webpackConfig (webpackConfig, vueOptions, api) {
fxy060608's avatar
fxy060608 已提交
159 160 161 162
    if (!webpackConfig.optimization) {
      webpackConfig.optimization = {}
    }
    // disable noEmitOnErrors
163 164 165 166 167
    if (webpack.version[0] > 4) {
      webpackConfig.optimization.emitOnErrors = true
    } else {
      webpackConfig.optimization.noEmitOnErrors = false
    }
fxy060608's avatar
fxy060608 已提交
168 169 170 171 172

    webpackConfig.optimization.runtimeChunk = {
      name: 'common/runtime'
    }

fxy060608's avatar
fxy060608 已提交
173
    webpackConfig.optimization.splitChunks = require('../split-chunks')()
fxy060608's avatar
fxy060608 已提交
174

Q
qiang 已提交
175 176 177 178
    if (webpack.version[0] > 4) {
      webpackConfig.optimization.chunkIds = 'named'
    }

fxy060608's avatar
fxy060608 已提交
179 180
    parseEntry()

fxy060608's avatar
fxy060608 已提交
181
    const statCode = getPlatformStat()
fxy060608's avatar
fxy060608 已提交
182
    const pushCode = getPlatformPush()
雪洛's avatar
雪洛 已提交
183
    const uniCloudCode = getPlatformUniCloud()
fxy060608's avatar
fxy060608 已提交
184

fxy060608's avatar
fxy060608 已提交
185
    let beforeCode = `import 'uni-pages';import '${uniModulesLoader}!';`
fxy060608's avatar
fxy060608 已提交
186 187 188 189

    const plugins = [
      new WebpackUniAppPlugin(),
      createUniMPPlugin(),
190 191
      new webpack.ProvidePlugin(getProvides()),
      ...createWxMpIndependentPlugins()
fxy060608's avatar
fxy060608 已提交
192 193
    ]

194
    if ((process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN) && process.env.UNI_SUBPACKGE !== 'main') {
fxy060608's avatar
fxy060608 已提交
195
      plugins.push(new PreprocessAssetsPlugin())
d-u-a's avatar
d-u-a 已提交
196
    }
fxy060608's avatar
fxy060608 已提交
197

198
    {
fxy060608's avatar
fxy060608 已提交
199
      const globalEnv = process.env.UNI_PLATFORM === 'mp-alipay' ? 'my' : 'wx';
200 201 202 203 204
      [].concat(
        process.env.UNI_MP_PLUGIN
          ? process.env.UNI_MP_PLUGIN_MAIN
          : JSON.parse(process.env.UNI_MP_PLUGIN_EXPORT)
      ).forEach(fileName => addToUniEntry(fileName))
雪洛's avatar
雪洛 已提交
205 206
      beforeCode += `
// @ts-ignore
fxy060608's avatar
fxy060608 已提交
207
${globalEnv}.__webpack_require_UNI_MP_PLUGIN__ = __webpack_require__;`
208 209
    }

fxy060608's avatar
fxy060608 已提交
210 211 212 213 214 215 216 217
    const alias = { // 仅 mp-weixin
      'mpvue-page-factory': require.resolve(
        '@dcloudio/vue-cli-plugin-uni/packages/mpvue-page-factory')
    }

    if (process.env.UNI_USING_VUE3) {
      alias.vuex = require.resolve('@dcloudio/vue-cli-plugin-uni/packages/vuex')
      alias['@vue/devtools-api'] = require.resolve('@dcloudio/vue-cli-plugin-uni/packages/@vue/devtools-api')
218 219 220

      alias['vue-i18n'] = require.resolve('@dcloudio/vue-cli-plugin-uni/packages/vue3/node_modules/vue-i18n')
      alias['@dcloudio/uni-app'] = require.resolve('@dcloudio/vue-cli-plugin-uni/packages/uni-app')
fxy060608's avatar
fxy060608 已提交
221 222
    }

Q
qiang 已提交
223 224
    // 使用外层依赖的版本
    alias['regenerator-runtime'] = require.resolve('regenerator-runtime')
fxy060608's avatar
fxy060608 已提交
225
    const output = {
fxy060608's avatar
fxy060608 已提交
226
      pathinfo: true,
fxy060608's avatar
fxy060608 已提交
227 228 229 230 231
      filename: '[name].js',
      chunkFilename: '[id].js',
      globalObject: process.env.UNI_PLATFORM === 'mp-alipay' ? 'my' : 'global'
      // sourceMapFilename: '../.sourcemap/' + process.env.UNI_PLATFORM + '/[name].js.map'
    }
fxy060608's avatar
fxy060608 已提交
232
    if (process.env.NODE_ENV === 'production' || process.env.UNI_MINIMIZE === 'true') {
fxy060608's avatar
fxy060608 已提交
233
      output.pathinfo = false
d-u-a's avatar
d-u-a 已提交
234 235 236 237 238 239
    }

    if (process.env.UNI_PLATFORM === 'mp-weixin' && process.env.NODE_ENV === 'production') {
      plugins.push(new UniTips())
    }

fxy060608's avatar
fxy060608 已提交
240
    return {
fxy060608's avatar
fxy060608 已提交
241
      mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
fxy060608's avatar
fxy060608 已提交
242 243 244
      entry () {
        return process.UNI_ENTRY
      },
fxy060608's avatar
fxy060608 已提交
245
      output,
fxy060608's avatar
fxy060608 已提交
246 247
      performance: {
        hints: false
fxy060608's avatar
fxy060608 已提交
248 249 250
      },
      resolve: {
        extensions: ['.nvue'],
fxy060608's avatar
fxy060608 已提交
251
        alias
fxy060608's avatar
fxy060608 已提交
252 253 254 255 256
      },
      module: {
        rules: [{
          test: path.resolve(process.env.UNI_INPUT_DIR, getMainEntry()),
          use: [{
257
            loader: path.resolve(__dirname, '../../packages/wrap-loader'),
fxy060608's avatar
fxy060608 已提交
258 259
            options: {
              before: [
雪洛's avatar
雪洛 已提交
260
                beforeCode + require('../util').getAutomatorCode() + statCode + pushCode + uniCloudCode
fxy060608's avatar
fxy060608 已提交
261 262 263
              ]
            }
          }, {
fxy060608's avatar
fxy060608 已提交
264 265 266 267 268 269 270 271 272 273 274
            loader: '@dcloudio/webpack-uni-mp-loader/lib/main'
          }]
        }, {
          resourceQuery: /vue&type=script/,
          use: [{
            loader: '@dcloudio/webpack-uni-mp-loader/lib/script'
          }]
        }, {
          resourceQuery: /vue&type=template/,
          use: [{
            loader: '@dcloudio/webpack-uni-mp-loader/lib/template'
275 276
          }, {
            loader: '@dcloudio/vue-cli-plugin-uni/packages/webpack-uni-app-loader/page-meta'
fxy060608's avatar
fxy060608 已提交
277
          }]
fxy060608's avatar
fxy060608 已提交
278
        }, createTemplateCacheLoader(api), {
fxy060608's avatar
fxy060608 已提交
279 280 281
          resourceQuery: [
            /lang=wxs/,
            /lang=filter/,
fxy060608's avatar
fxy060608 已提交
282
            /lang=sjs/,
fxy060608's avatar
fxy060608 已提交
283 284
            /blockType=wxs/,
            /blockType=filter/,
fxy060608's avatar
fxy060608 已提交
285
            /blockType=sjs/
fxy060608's avatar
fxy060608 已提交
286
          ],
fxy060608's avatar
fxy060608 已提交
287 288 289 290
          use: [{
            loader: require.resolve(
              '@dcloudio/vue-cli-plugin-uni/packages/webpack-uni-filter-loader')
          }]
fxy060608's avatar
fxy060608 已提交
291 292
        }]
      },
fxy060608's avatar
fxy060608 已提交
293
      plugins
fxy060608's avatar
fxy060608 已提交
294 295
    }
  },
fxy060608's avatar
fxy060608 已提交
296
  chainWebpack (webpackConfig, vueOptions, api) {
fxy060608's avatar
fxy060608 已提交
297 298 299 300 301 302 303
    if (process.env.UNI_PLATFORM === 'mp-baidu') {
      webpackConfig.module
        .rule('js')
        .exclude
        .add(/\.filter\.js$/)
    }

fxy060608's avatar
fxy060608 已提交
304
    const compilerOptions = process.env.UNI_USING_COMPONENTS ? {} : require('../mp-compiler-options')
fxy060608's avatar
fxy060608 已提交
305

306
    modifyVueLoader(webpackConfig, {}, compilerOptions, api)
fxy060608's avatar
fxy060608 已提交
307

fxy060608's avatar
fxy060608 已提交
308 309
    const styleExt = getPlatformExts().style

fxy060608's avatar
fxy060608 已提交
310 311
    webpackConfig.plugin('extract-css')
      .init((Plugin, args) => new Plugin({
fxy060608's avatar
fxy060608 已提交
312
        filename: '[name]' + styleExt
fxy060608's avatar
fxy060608 已提交
313 314
      }))

fxy060608's avatar
fxy060608 已提交
315 316 317 318
    if (
      process.env.NODE_ENV === 'production' &&
      process.env.UNI_PLATFORM !== 'app-plus'
    ) {
Q
qiang 已提交
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
      // webpack5 不再使用 OptimizeCssnanoPlugin,改用 CssMinimizerPlugin
      if (webpack.version[0] > 4) {
        webpackConfig.optimization.minimizer('css').tap(args => {
          args[0].test = new RegExp(`\\${styleExt}$`)
          return args
        })
      } else {
        const OptimizeCssnanoPlugin = require('../../packages/@intervolga/optimize-cssnano-plugin/index.js')
        webpackConfig.plugin('optimize-css')
          .init((Plugin, args) => new OptimizeCssnanoPlugin({
            sourceMap: false,
            filter (assetName) {
              return path.extname(assetName) === styleExt
            },
            cssnanoOptions: {
              preset: [
                'default',
                Object.assign({}, getPlatformCssnano(), {
                  discardComments: true
                })
              ]
            }
          }))
      }
fxy060608's avatar
fxy060608 已提交
343 344
    }

Q
qiang 已提交
345 346 347 348 349
    if (process.env.NODE_ENV === 'production' && webpack.version[0] > 4) {
      // 暂时禁用,否则导致 provide 被压缩和裁剪
      webpackConfig.optimization.usedExports(false)
    }

350
    if (process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN) {
fxy060608's avatar
fxy060608 已提交
351 352 353
      initSubpackageConfig(webpackConfig, vueOptions)
    }

fxy060608's avatar
fxy060608 已提交
354 355 356 357 358 359
    webpackConfig.plugins.delete('hmr')
    webpackConfig.plugins.delete('html')
    webpackConfig.plugins.delete('copy')
    webpackConfig.plugins.delete('preload')
    webpackConfig.plugins.delete('prefetch')
  }
雪洛's avatar
雪洛 已提交
360
}