1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16const path = require('path');
17const fs = require('fs');
18const webpack = require('webpack');
19const TerserPlugin = require('terser-webpack-plugin');
20const SnapshotPlugin = require('./lib/lite/lite-snapshot-plugin');
21const ImageCoverterPlugin = require('./lib/lite/lite-image-coverter-plugin');
22const ReturnExportsPlugin = require('./lib/lite/lite-return-exports-plugin');
23const ResourcePlugin = require('./lib/resource-plugin');
24const ResultStates = require('./lib/compile-plugin');
25const { checkFilePath } = require('./lib/lite/lite-customize');
26const CopyPlugin = require("copy-webpack-plugin");
27
28process.env.DEVICE_LEVEL = 'lite';
29process.env.DEVICE_TYPE = 'smartVision';
30
31const watchMode = (process.env.watchMode && process.env.watchMode === 'true') || false;
32const pictrueSwitch = process.env.img2bin !== 'false';
33const util = require('./lib/util');
34const { PLATFORM }= require('./lib/lite/lite-enum');
35const { deleteFolderRecursive, readManifest, loadEntryObj, checkMultiResourceBuild } = require('./main.product');
36
37const webpackConfig = {
38  target: ['web', 'es5'],
39  cache: {
40    type: 'filesystem'
41  },
42  watch: watchMode,
43  watchOptions: {
44    aggregateTimeout: 10,
45    poll: false,
46    ignored: /node_modules/,
47  },
48  optimization: {
49    moduleIds: 'deterministic',
50    chunkIds: 'deterministic',
51  },
52  output: {
53    filename: '[name].js',
54    pathinfo: false,
55    devtoolModuleFilenameTemplate: (info) => {
56      return `${info.absoluteResourcePath.replace(process.env.projectRootPath + path.sep, '')}`;
57    },
58  },
59  devtool: 'nosources-source-map',
60  mode: 'development',
61  module: {
62    rules: [
63      {
64        test: /(\.hml|app\.js)(\?[^?]+)?$/,
65        use: [{
66          loader: path.resolve(__dirname, './index.js')
67        }]
68      },
69      {
70        test: /\.png$/,
71        use: [{
72          loader: 'file-loader',
73          options: {
74            name: '[name].[ext]', outputPath: 'common'
75          }
76        }]
77      },
78      {
79        test: /\.css$/,
80        use: [{
81          loader: 'css-loader'
82        }]
83      },
84      {
85        test: /\.less$/,
86        use: [{
87          loader: 'less-loader'
88        }]
89      },
90      {
91        test: /\.(scss|sass)$/,
92        use: [{
93          loader: 'style-loader!css-loader!sass-loader'
94        }]
95      },
96      {
97        test: /\.jsx?$/,
98        use: [
99          {
100            loader: path.resolve(__dirname, 'lib/module-script.js'),
101          },
102          {
103            loader: util.loadBabelModule('babel-loader'),
104            options: {
105              presets: [util.loadBabelModule('@babel/preset-env')],
106              plugins: [util.loadBabelModule('@babel/plugin-transform-modules-commonjs'),
107              util.loadBabelModule('@babel/plugin-proposal-class-properties')],
108            },
109          },
110        ]
111      }
112    ]
113  },
114  node: {
115    global: false,
116  },
117  stats: 'none',
118};
119
120function setConfigs(env) {
121  process.env.error = env.error === undefined ? true : env.error
122  process.env.warning = env.warning === undefined ? true : env.warning
123  process.env.note = env.note === undefined ? true : env.note
124  process.env.buildMode = env.buildMode || 'debug'
125  process.env.logLevel = env.logLevel || '1'
126  process.env.projectPath = env.aceModuleRoot || process.env.aceModuleRoot || process.cwd();
127  process.env.buildPath = env.aceModuleBuild || process.env.aceModuleBuild || path.resolve(process.env.projectPath, 'build');
128  process.env.cachePath = env.cachePath || process.env.cachePath || path.resolve(__dirname, 'node_modules/.cache');
129  process.env.aceManifestPath = process.env.aceManifestPath || path.resolve(process.env.projectPath, 'manifest.json');
130  process.env.watchCSSFiles = process.env.watchCSSFiles || path.resolve(process.env.cachePath, '.lite_cache', 'preview_css.json');
131  process.env.abilityType = 'page';
132  const manifest = readManifest(process.env.aceManifestPath)
133  process.env.PLATFORM_VERSION = PLATFORM.VERSION6;
134  const version = parseInt(manifest.minPlatformVersion);
135  if (version == 5) {
136    process.env.PLATFORM_VERSION = PLATFORM.VERSION5;
137  }
138  if (version <= 4) {
139    process.env.PLATFORM_VERSION = PLATFORM.VERSION3;
140  }
141  process.env.PLATFORM_VERSION_VERSION = version;
142  process.env.aceBuildJson = env.aceBuildJson || process.env.aceBuildJson;
143  checkMultiResourceBuild(process.env.aceBuildJson);
144}
145
146module.exports = (env) => {
147  setConfigs(env)
148  deleteFolderRecursive(process.env.buildPath);
149  webpackConfig.cache.cacheDirectory = path.resolve(process.env.cachePath, '.lite_cache');
150  webpackConfig.entry = loadEntryObj(process.env.projectPath, process.env.DEVICE_LEVEL,
151    process.env.abilityType, process.env.aceManifestPath)
152  webpackConfig.output.path = path.resolve(__dirname, process.env.buildPath)
153  webpackConfig.plugins = [
154    new ResourcePlugin(process.env.projectPath, process.env.buildPath,
155      process.env.aceManifestPath, process.env.watchCSSFiles),
156    new ResultStates({
157      build: process.env.buildPath
158    }),
159    new ReturnExportsPlugin(),
160    new webpack.DefinePlugin({
161      STANDARD: JSON.stringify(false),
162      LITE: JSON.stringify(true)
163    })
164  ]
165  webpackConfig.resolve = {
166    modules: [
167      process.env.projectPath,
168      path.join(process.env.projectPath, '../../../../../'),
169      path.join(__dirname, 'node_modules'),
170      './node_modules',
171      './oh_modules'
172    ]
173  }
174  if (fs.existsSync(path.resolve(process.env.projectPath, 'i18n'))) {
175    webpackConfig.plugins.push(new CopyPlugin({
176      patterns: [
177        {
178          from: path.resolve(process.env.projectPath, 'i18n'),
179          to: path.resolve(process.env.buildPath, 'i18n'),
180          noErrorOnMissing: true
181        }
182      ]
183    }))
184  }
185
186  if (process.env.hapMode && process.env.hapMode === 'true') {
187    webpackConfig.optimization = {
188      minimize: true,
189      minimizer: [new TerserPlugin({
190        terserOptions: {
191          compress: false,
192          mangle: true,
193        },
194      },
195      )],
196    };
197  }
198
199  if (pictrueSwitch) {
200    webpackConfig.plugins.push(
201      new ImageCoverterPlugin({ build: process.env.buildPath }),
202    );
203  }
204
205  if (env.deviceType) {
206    const deviceArr = env.deviceType.split(/,/);
207    if (deviceArr.includes('liteWearable')) {
208      process.env.DEVICE_TYPE = 'liteWearable';
209    }
210  }
211
212  if (env.sourceMap === 'none') {
213    webpackConfig.devtool = false
214  }
215  if (env.buildMode === 'release') {
216    webpackConfig.devtool = 'source-map'
217    webpackConfig.mode = 'production';
218    webpackConfig.plugins.push(
219      new SnapshotPlugin({ build: process.env.buildPath })
220    );
221    webpackConfig.output.sourceMapFilename = '_releaseMap/[name].js.map'
222  }
223  checkFilePath();
224  return webpackConfig;
225};
226