index.js 9.6 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 9 10 11
  getPlatformExts,
  getPlatformCssnano
} = require('@dcloudio/uni-cli-shared')

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

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

fxy060608's avatar
fxy060608 已提交
16
const {
fxy060608's avatar
fxy060608 已提交
17
  createTemplateCacheLoader
fxy060608's avatar
fxy060608 已提交
18
} = require('../cache-loader')
fxy060608's avatar
fxy060608 已提交
19

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

function getProvides () {
fxy060608's avatar
fxy060608 已提交
26
  const uniPath = require('@dcloudio/uni-cli-shared/lib/platform').getMPRuntimePath()
fxy060608's avatar
fxy060608 已提交
27
  const uniCloudPath = path.resolve(__dirname, '../../packages/uni-cloud/dist/index.js')
fxy060608's avatar
fxy060608 已提交
28
  const provides = {
fxy060608's avatar
fxy060608 已提交
29 30
    uni: [uniPath, 'default'],
    uniCloud: [uniCloudPath, 'default']
fxy060608's avatar
fxy060608 已提交
31 32
  }

fxy060608's avatar
fxy060608 已提交
33 34 35 36 37
  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 已提交
38
  if (process.env.UNI_USING_COMPONENTS) {
fxy060608's avatar
fxy060608 已提交
39 40
    if (process.env.UNI_SUBPACKGE) {
      provides.createApp = [uniPath, 'createSubpackageApp']
41 42
    } else if (process.env.UNI_MP_PLUGIN) {
      provides.createApp = [uniPath, 'createPlugin']
fxy060608's avatar
fxy060608 已提交
43 44 45
    } else {
      provides.createApp = [uniPath, 'createApp']
    }
fxy060608's avatar
fxy060608 已提交
46 47
    provides.createPage = [uniPath, 'createPage']
    provides.createComponent = [uniPath, 'createComponent']
fxy060608's avatar
fxy060608 已提交
48 49 50 51 52 53
  }

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

fxy060608's avatar
fxy060608 已提交
56
    const cryptoProvide = [path.resolve(__dirname, '../crypto.js'), 'default']
fxy060608's avatar
fxy060608 已提交
57
    provides.crypto = cryptoProvide
58 59
    provides['window.crypto'] = cryptoProvide
    provides['global.crypto'] = cryptoProvide
fxy060608's avatar
fxy060608 已提交
60 61 62 63 64 65 66 67
  }

  // 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 已提交
68
    provides.wx = provides.uni
fxy060608's avatar
fxy060608 已提交
69 70 71 72
  }
  return provides
}

fxy060608's avatar
fxy060608 已提交
73 74
function processWxss (name, assets) {
  const dirname = path.dirname(name)
75
  const mainWxssCode = `@import "${normalizePath(path.relative(dirname, 'common/main.wxss'))}";`
fxy060608's avatar
fxy060608 已提交
76 77 78 79 80 81 82 83 84 85 86 87 88
  const code = `${mainWxssCode}` + assets[name].source().toString()
  assets[name] = {
    size () {
      return Buffer.byteLength(code, 'utf8')
    },
    source () {
      return code
    }
  }
}

function procssJs (name, assets, hasVendor) {
  const dirname = path.dirname(name)
89 90 91
  const runtimeJsCode = `require('${normalizePath(path.relative(dirname, 'common/runtime.js'))}');`
  const vendorJsCode = hasVendor ? `require('${normalizePath(path.relative(dirname, 'common/vendor.js'))}');` : ''
  const mainJsCode = `require('${normalizePath(path.relative(dirname, 'common/main.js'))}');`
fxy060608's avatar
fxy060608 已提交
92 93 94 95 96 97 98 99 100 101 102
  const code = `${runtimeJsCode}${vendorJsCode}${mainJsCode}` + assets[name].source().toString()
  assets[name] = {
    size () {
      return Buffer.byteLength(code, 'utf8')
    },
    source () {
      return code
    }
  }
}

fxy060608's avatar
fxy060608 已提交
103 104 105 106
class PreprocessAssetsPlugin {
  apply (compiler) {
    compiler.hooks.emit.tap('PreprocessAssetsPlugin', compilation => {
      const assets = compilation.assets
fxy060608's avatar
fxy060608 已提交
107
      const hasMainWxss = assets['common/main.wxss']
fxy060608's avatar
fxy060608 已提交
108 109 110 111 112
      const hasVendor = assets['common/vendor.js']
      Object.keys(assets).forEach(name => {
        if (name.startsWith('common')) {
          return
        }
fxy060608's avatar
fxy060608 已提交
113 114 115 116 117
        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 已提交
118 119
        }
      })
fxy060608's avatar
fxy060608 已提交
120
      // delete assets['common/main.js']
fxy060608's avatar
fxy060608 已提交
121 122 123 124 125 126 127 128 129
      delete assets['app.js']
      delete assets['app.json']
      delete assets['app.wxss']
      delete assets['project.config.json']
    })
  }
}

function initSubpackageConfig (webpackConfig, vueOptions) {
130
  if (process.env.UNI_OUTPUT_DEFAULT_DIR === process.env.UNI_OUTPUT_DIR) { // 未自定义output
fxy060608's avatar
fxy060608 已提交
131 132
    process.env.UNI_OUTPUT_DIR = path.resolve(process.env.UNI_OUTPUT_DIR, (process.env.UNI_SUBPACKGE || process.env
      .UNI_MP_PLUGIN))
133
  }
fxy060608's avatar
fxy060608 已提交
134 135
  vueOptions.outputDir = process.env.UNI_OUTPUT_DIR
  webpackConfig.output.path(process.env.UNI_OUTPUT_DIR)
136
  webpackConfig.output.jsonpFunction('webpackJsonp_' + (process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN))
fxy060608's avatar
fxy060608 已提交
137 138
}

fxy060608's avatar
fxy060608 已提交
139 140 141 142
module.exports = {
  vueConfig: {
    parallel: false
  },
fxy060608's avatar
fxy060608 已提交
143
  webpackConfig (webpackConfig, vueOptions, api) {
fxy060608's avatar
fxy060608 已提交
144 145 146 147 148 149 150 151 152 153
    if (!webpackConfig.optimization) {
      webpackConfig.optimization = {}
    }
    // disable noEmitOnErrors
    webpackConfig.optimization.noEmitOnErrors = false

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

fxy060608's avatar
fxy060608 已提交
154
    webpackConfig.optimization.splitChunks = require('../split-chunks')()
fxy060608's avatar
fxy060608 已提交
155 156 157

    parseEntry()

fxy060608's avatar
fxy060608 已提交
158
    const statCode = process.env.UNI_USING_STAT ? 'import \'@dcloudio/uni-stat\';' : ''
fxy060608's avatar
fxy060608 已提交
159

160
    let beforeCode = 'import \'uni-pages\';'
fxy060608's avatar
fxy060608 已提交
161 162 163 164 165 166 167

    const plugins = [
      new WebpackUniAppPlugin(),
      createUniMPPlugin(),
      new webpack.ProvidePlugin(getProvides())
    ]

168
    if ((process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN) && process.env.UNI_SUBPACKGE !== 'main') {
fxy060608's avatar
fxy060608 已提交
169 170
      plugins.push(new PreprocessAssetsPlugin())
    }
fxy060608's avatar
fxy060608 已提交
171

172 173 174
    if (process.env.UNI_MP_PLUGIN) {
      // 小程序插件入口使用
      // packages\webpack-uni-mp-loader\lib\plugin\index-new.js -> addMPPluginRequire
175
      beforeCode += `wx.__webpack_require_${process.env.UNI_MP_PLUGIN.replace('-', '_')}__ = __webpack_require__;`
176 177 178

      const UNI_MP_PLUGIN_MAIN = process.env.UNI_MP_PLUGIN_MAIN
      if (UNI_MP_PLUGIN_MAIN) {
fxy060608's avatar
fxy060608 已提交
179 180
        process.UNI_ENTRY[UNI_MP_PLUGIN_MAIN.split('.')[0]] = path.resolve(process.env.UNI_INPUT_DIR,
          UNI_MP_PLUGIN_MAIN)
181 182 183
      }
    }

fxy060608's avatar
fxy060608 已提交
184
    return {
fxy060608's avatar
fxy060608 已提交
185
      mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
fxy060608's avatar
fxy060608 已提交
186 187 188 189 190 191
      entry () {
        return process.UNI_ENTRY
      },
      output: {
        filename: '[name].js',
        chunkFilename: '[id].js',
fxy060608's avatar
fxy060608 已提交
192 193
        globalObject: process.env.UNI_PLATFORM === 'mp-alipay' ? 'my' : 'global'
        // sourceMapFilename: '../.sourcemap/' + process.env.UNI_PLATFORM + '/[name].js.map'
fxy060608's avatar
fxy060608 已提交
194 195 196
      },
      performance: {
        hints: false
fxy060608's avatar
fxy060608 已提交
197 198 199 200 201 202 203 204 205 206 207 208
      },
      resolve: {
        extensions: ['.nvue'],
        alias: { // 仅 mp-weixin
          'mpvue-page-factory': require.resolve(
            '@dcloudio/vue-cli-plugin-uni/packages/mpvue-page-factory')
        }
      },
      module: {
        rules: [{
          test: path.resolve(process.env.UNI_INPUT_DIR, getMainEntry()),
          use: [{
209
            loader: path.resolve(__dirname, '../../packages/wrap-loader'),
fxy060608's avatar
fxy060608 已提交
210 211
            options: {
              before: [
fxy060608's avatar
fxy060608 已提交
212
                beforeCode + require('../util').getAutomatorCode() + statCode
fxy060608's avatar
fxy060608 已提交
213 214 215
              ]
            }
          }, {
fxy060608's avatar
fxy060608 已提交
216 217 218 219 220 221 222 223 224 225 226
            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'
227 228
          }, {
            loader: '@dcloudio/vue-cli-plugin-uni/packages/webpack-uni-app-loader/page-meta'
fxy060608's avatar
fxy060608 已提交
229
          }]
fxy060608's avatar
fxy060608 已提交
230
        }, createTemplateCacheLoader(api), {
fxy060608's avatar
fxy060608 已提交
231 232 233
          resourceQuery: [
            /lang=wxs/,
            /lang=filter/,
fxy060608's avatar
fxy060608 已提交
234
            /lang=sjs/,
fxy060608's avatar
fxy060608 已提交
235 236
            /blockType=wxs/,
            /blockType=filter/,
fxy060608's avatar
fxy060608 已提交
237
            /blockType=sjs/
fxy060608's avatar
fxy060608 已提交
238
          ],
fxy060608's avatar
fxy060608 已提交
239 240 241 242
          use: [{
            loader: require.resolve(
              '@dcloudio/vue-cli-plugin-uni/packages/webpack-uni-filter-loader')
          }]
fxy060608's avatar
fxy060608 已提交
243 244
        }]
      },
fxy060608's avatar
fxy060608 已提交
245
      plugins
fxy060608's avatar
fxy060608 已提交
246 247
    }
  },
fxy060608's avatar
fxy060608 已提交
248
  chainWebpack (webpackConfig, vueOptions, api) {
fxy060608's avatar
fxy060608 已提交
249 250 251 252 253 254 255
    if (process.env.UNI_PLATFORM === 'mp-baidu') {
      webpackConfig.module
        .rule('js')
        .exclude
        .add(/\.filter\.js$/)
    }

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

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

fxy060608's avatar
fxy060608 已提交
260 261
    const styleExt = getPlatformExts().style

fxy060608's avatar
fxy060608 已提交
262 263
    webpackConfig.plugin('extract-css')
      .init((Plugin, args) => new Plugin({
fxy060608's avatar
fxy060608 已提交
264
        filename: '[name]' + styleExt
fxy060608's avatar
fxy060608 已提交
265 266
      }))

fxy060608's avatar
fxy060608 已提交
267 268 269 270
    if (
      process.env.NODE_ENV === 'production' &&
      process.env.UNI_PLATFORM !== 'app-plus'
    ) {
fxy060608's avatar
fxy060608 已提交
271
      const OptimizeCssnanoPlugin = require('../../packages/@intervolga/optimize-cssnano-plugin/index.js')
fxy060608's avatar
fxy060608 已提交
272
      webpackConfig.plugin('optimize-css')
fxy060608's avatar
fxy060608 已提交
273
        .init((Plugin, args) => new OptimizeCssnanoPlugin({
fxy060608's avatar
fxy060608 已提交
274
          sourceMap: false,
fxy060608's avatar
fxy060608 已提交
275 276 277
          filter (assetName) {
            return path.extname(assetName) === styleExt
          },
fxy060608's avatar
fxy060608 已提交
278 279 280
          cssnanoOptions: {
            preset: [
              'default',
fxy060608's avatar
fxy060608 已提交
281 282 283
              Object.assign({}, getPlatformCssnano(), {
                discardComments: true
              })
fxy060608's avatar
fxy060608 已提交
284 285 286 287 288 289
            ]
          }

        }))
    }

290
    if (process.env.UNI_SUBPACKGE || process.env.UNI_MP_PLUGIN) {
fxy060608's avatar
fxy060608 已提交
291 292 293
      initSubpackageConfig(webpackConfig, vueOptions)
    }

fxy060608's avatar
fxy060608 已提交
294 295 296 297 298 299
    webpackConfig.plugins.delete('hmr')
    webpackConfig.plugins.delete('html')
    webpackConfig.plugins.delete('copy')
    webpackConfig.plugins.delete('preload')
    webpackConfig.plugins.delete('prefetch')
  }
fxy060608's avatar
fxy060608 已提交
300
}