| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- const fs = require('fs');
- const path = require('path');
- const CopyWebpackPlugin = require('copy-webpack-plugin');
- const ReplaceInFileWebpackPlugin = require('replace-in-file-webpack-plugin');
- const TerserPlugin = require('terser-webpack-plugin');
- const MiniCssExtractPlugin = require('mini-css-extract-plugin');
- const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
- const HtmlWebpackPlugin = require('html-webpack-plugin');
- import * as webpack from 'webpack';
- import { getStyleLoaders, getStylesheetEntries, getFileLoaders } from './webpack/loaders';
- interface WebpackConfigurationOptions {
- watch?: boolean;
- production?: boolean;
- }
- type WebpackConfigurationGetter = (options: WebpackConfigurationOptions) => webpack.Configuration;
- const findModuleTs = (base: string, files?: string[], result?: string[]) => {
- files = files || fs.readdirSync(base);
- result = result || [];
- if (files) {
- files.forEach(file => {
- const newbase = path.join(base, file);
- if (fs.statSync(newbase).isDirectory()) {
- result = findModuleTs(newbase, fs.readdirSync(newbase), result);
- } else {
- if (file.indexOf('module.ts') > -1) {
- // @ts-ignore
- result.push(newbase);
- }
- }
- });
- }
- return result;
- };
- const getModuleFiles = () => {
- return findModuleTs(path.resolve(process.cwd(), 'src'));
- };
- const getManualChunk = (id: string) => {
- if (id.endsWith('module.ts') || id.endsWith('module.tsx')) {
- const idx = id.lastIndexOf(path.sep + 'src' + path.sep);
- if (idx > 0) {
- const name = id.substring(idx + 5, id.lastIndexOf('.'));
- return {
- name,
- module: id,
- };
- }
- }
- return null;
- };
- const getEntries = () => {
- const entries: { [key: string]: string } = {};
- const modules = getModuleFiles();
- modules.forEach(modFile => {
- const mod = getManualChunk(modFile);
- // @ts-ignore
- entries[mod.name] = mod.module;
- });
- return {
- ...entries,
- ...getStylesheetEntries(),
- };
- };
- const getCommonPlugins = (options: WebpackConfigurationOptions) => {
- const packageJson = require(path.resolve(process.cwd(), 'package.json'));
- return [
- new MiniCssExtractPlugin({
- // both options are optional
- filename: 'styles/[name].css',
- }),
- new webpack.optimize.OccurrenceOrderPlugin(true),
- new CopyWebpackPlugin(
- [
- { from: 'plugin.json', to: '.' },
- { from: '../README.md', to: '.' },
- { from: '../LICENSE', to: '.' },
- { from: 'img/*', to: '.' },
- { from: '**/*.json', to: '.' },
- { from: '**/*.svg', to: '.' },
- { from: '**/*.png', to: '.' },
- { from: '**/*.html', to: '.' },
- ],
- { logLevel: options.watch ? 'silent' : 'warn' }
- ),
- new ReplaceInFileWebpackPlugin([
- {
- dir: 'dist',
- files: ['plugin.json', 'README.md'],
- rules: [
- {
- search: '%VERSION%',
- replace: packageJson.version,
- },
- {
- search: '%TODAY%',
- replace: new Date().toISOString().substring(0, 10),
- },
- ],
- },
- ]),
- ];
- };
- export const getWebpackConfig: WebpackConfigurationGetter = options => {
- const plugins = getCommonPlugins(options);
- const optimization: { [key: string]: any } = {};
- if (options.production) {
- optimization.minimizer = [new TerserPlugin(), new OptimizeCssAssetsPlugin()];
- } else if (options.watch) {
- plugins.push(new HtmlWebpackPlugin());
- }
- return {
- mode: options.production ? 'production' : 'development',
- target: 'web',
- node: {
- fs: 'empty',
- net: 'empty',
- tls: 'empty',
- },
- context: path.join(process.cwd(), 'src'),
- devtool: 'source-map',
- entry: getEntries(),
- output: {
- filename: '[name].js',
- path: path.join(process.cwd(), 'dist'),
- libraryTarget: 'amd',
- publicPath: '/',
- },
- performance: { hints: false },
- externals: [
- 'lodash',
- 'jquery',
- 'moment',
- 'slate',
- 'emotion',
- 'prismjs',
- 'slate-plain-serializer',
- 'slate-react',
- 'react',
- 'react-dom',
- 'rxjs',
- 'd3',
- 'angular',
- '@grafana/ui',
- '@grafana/runtime',
- '@grafana/data',
- // @ts-ignore
- (context, request, callback) => {
- const prefix = 'grafana/';
- if (request.indexOf(prefix) === 0) {
- return callback(null, request.substr(prefix.length));
- }
- // @ts-ignore
- callback();
- },
- ],
- plugins,
- resolve: {
- extensions: ['.ts', '.tsx', '.js'],
- modules: [path.resolve(process.cwd(), 'src'), 'node_modules'],
- },
- module: {
- rules: [
- {
- test: /\.tsx?$/,
- loaders: [
- {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env'],
- plugins: ['angularjs-annotate'],
- },
- },
- {
- loader: 'ts-loader',
- options: { onlyCompileBundledFiles: true },
- },
- ],
- exclude: /(node_modules)/,
- },
- ...getStyleLoaders(),
- {
- test: /\.html$/,
- exclude: [/node_modules/],
- use: {
- loader: 'html-loader',
- },
- },
- ...getFileLoaders(),
- ],
- },
- optimization,
- // optimization: {
- // splitChunks: {
- // chunks: 'all',
- // name: 'shared'
- // }
- // }
- };
- };
|