riant-scripts

1.3.0 • Public • Published

riant-scripts

npm package

Create your app using create-react-app , and tweak the create-react-app webpack config(s) , especially preset less-loader and stylus-loader .

NPM version NPM Downloads

中文文档

Install riant-scripts

$ npm install riant-scripts --save-dev

Schema

/* riant.config.js */
module.exports = {
  alias: { instanceof: ['Function', 'Object'] },
  babelPlugins: { instanceof: ['Function', 'Array'] },
  chainWebpack: { instanceof: 'Function' },
  configureWebpack: { instanceof: 'Function' },
  css: {
    type: 'object',
    properties: {
      modules: { type: 'boolean' },
      sourceMap: { type: 'boolean' },
      loaderOptions: {
        type: 'object',
        properties: {
          css: { type: 'object' },
          less: { type: 'object' },
          stylus: { type: 'object' },
          postcss: { type: 'object' }
        }
      }
    }
  },
  devServer: { instanceof: ['Function', 'Object'] },
  extensions: { instanceof: ['Function', 'Array'] },
  externals: { instanceof: ['Function', 'Array', 'RegExp', 'Object'] },
  filenameHashing: { type: 'boolean' },
  jest: { instanceof: ['Function', 'Object'] },
  pages: { type: 'object' },
  parallel: { type: ['boolean', 'number'] },
  paths: { instanceof: ['Function', 'Object'] },
  riantPlugins: { instanceof: 'Array' },
  useEslintrc: { type: 'boolean' }
}

Create a riant.config.js file in the root directory

  • Create aliases to import or require certain modules more easily
/* riant.config.js */
module.exports = {
  alias: {
    '@': path.join(__dirname, 'src')
  }
}
/* riant.config.js */
module.exports = {
  alias(chainedMap, env) {
    chainedMap.set('@', path.join(__dirname, 'src'));
  }
}
  • Add plugins to Babel
/* riant.config.js */
module.exports = {
  babelPlugins: [
    [
      'import',
      {
        libraryName: 'antd',
        libraryDirectory: 'es',
        style: 'css',
      },
      'fix-import-imports'
    ], 
    ['@babel/plugin-proposal-decorators', { legacy: true }]
  ]
}
/* riant.config.js */
module.exports = {
  babelPlugins(plugins, env) {
    plugins.push(
      [
        'import',
        {
          libraryName: 'antd',
          libraryDirectory: 'es',
          style: 'css',
        },
        'fix-import-imports'
      ],
      ['@babel/plugin-proposal-decorators', { legacy: true }]
    );
  }
}
/* riant.config.js */
module.exports = {
  babelPlugins(plugins, env) {
    return plugins.concat([
      [
        'import',
        {
          libraryName: 'antd',
          libraryDirectory: 'es',
          style: 'css',
        },
        'fix-import-imports'
      ],
      ['@babel/plugin-proposal-decorators', { legacy: true }]
    ]);
  }
}
  • Customize Webpack config
/* riant.config.js */
module.exports = {
  chainWebpack(chainedConfig, env) {
    if (env === 'production') {
      // supporting Internet Explorer 9
      chainedConfig
        .entry('main')
        .prepend(require.resolve('react-app-polyfill/stable'))
        .prepend(require.resolve('react-app-polyfill/ie9'));
 
      // without `console.log`
      chainedConfig.optimization.minimizer('TerserPlugin').init((plugin) => {
        plugin.options.terserOptions.compress.pure_funcs = ['console.log'];
        return plugin;
      });
    }
 
    // code splitting
    if (env !== 'test') {
      chainedConfig
        .optimization.splitChunks({
          cacheGroups: {
            vendors: {
              name: `chunk-vendors`,
              test: /[\\/]node_modules[\\/]/,
              priority: -10,
              chunks: 'initial'
            },
            common: {
              name: `chunk-common`,
              minChunks: 2,
              priority: -20,
              chunks: 'initial',
              reuseExistingChunk: true
            }
          }
        });
    }
  }
}
/* riant.config.js */
module.exports = {
  configureWebpack(objectConfig, env) {
    if (env === 'production') {
      // without `console.log`
      objectConfig
        .optimization
        .minimizer[0]
        .options
        .terserOptions
        .compress
        .pure_funcs = ['console.log'];
    }
  }
}
  • Customize style loader options
/* riant.config.js */
module.exports = {
  css: {
    loaderOptions: {
      stylus: {
        define: {
          '$cdn': 'https://cdn.jsdelivr.net'
        }
      }
    }
  }
}
  • Customize Dev Server config
/* riant.config.js */
module.exports = {
  devServer: { 
    proxy: {
      '/api': {
        target: 'http://localhost:8088',
        changeOrigin: true
      }
    },
  }
}
/* riant.config.js */
module.exports = {
  devServer(devConfig, env) {
    devConfig.proxy = {
      '/api': {
        target: 'http://localhost:8088',
        changeOrigin: true
      }
    };
  }
}
  • Attempt to resolve these extensions in order
/* riant.config.js */
module.exports = {
  extensions: ['.properties']
}
/* riant.config.js */
module.exports = {
  extensions(chainedSet, env) {
    chainedSet.add('.properties');
  }
}
  • Prevent bundling of certain imported packages and instead retrieve these external dependencies at runtime
/* riant.config.js */
module.exports = {
  externals: {
    jquery: 'jQuery'
  }
}
/* riant.config.js */
module.exports = {
  externals() {
    return {
      jquery: 'jQuery'
    };
  }
}
  • Attempt to remove hash from filename
/* riant.config.js */
module.exports = {
  filenameHashing: false
}
  • Attempt to update jest config
/* riant.config.js */
module.exports = {
  jest(jestConfig) {
    return jestConfig;
  }
}
  • multi-page setup
/* riant.config.js */
module.exports = {
  pages: {
    home: 'src/home.js',
    form: 'src/form.js',
    notfound: 'src/notfound.js'
  }
}
  • Attempt to update paths
/* riant.config.js */
module.exports = {
  paths: { 
 
  }
}
/* riant.config.js */
module.exports = {
  paths(pathsConfig, env) {
 
  }
}
  • use thread-loader for Babel or TypeScript transpilation
/* riant.config.js */
module.exports = {
  parallel: true
}
  • Add progress bar
/* riant.config.js */
module.exports = {
  progressBar: true
}
  • Add plugins to riant-scripts
/* riant.config.js */
module.exports = {
  riantPlugins: [
    function (service, projectOptions) {
 
    }
  ]
}

plugins reference

  • Use eslintrc
/* riant.config.js */
module.exports = {
  useEslintrc: true
}

Extended Webpack Configuration

  • supporting Internet Explorer 9
/* riant.config.js */
module.exports = {
  chainWebpack(chainedConfig, env) {
    if (env === 'production') {
      chainedConfig
        .entry('main')
        .prepend(require.resolve('react-app-polyfill/stable'))
        .prepend(require.resolve('react-app-polyfill/ie9'));
    }
}
  • without console.log
/* riant.config.js */
module.exports = {
  chainWebpack(chainedConfig, env) {
    if (env === 'production') {
      chainedConfig.optimization
        .minimizer('TerserPlugin')
        .init((plugin) => {
          plugin.options.terserOptions.compress.pure_funcs = ['console.log'];
          return plugin;
        });
    }
}
  • code splitting
/* riant.config.js */
module.exports = {
  chainWebpack(chainedConfig, env) {
    if (env !== 'test') {
      chainedConfig.optimization
        .splitChunks({
          cacheGroups: {
            vendors: {
              name: `chunk-vendors`,
              test: /[\\/]node_modules[\\/]/,
              priority: -10,
              chunks: 'initial'
            },
            common: {
              name: `chunk-common`,
              minChunks: 2,
              priority: -20,
              chunks: 'initial',
              reuseExistingChunk: true
            }
          }
        });
    }
}

Create .env.production file in the root directory

  • Set env for production
# Source maps are resource heavy and can cause out of memory issue for large source files.
GENERATE_SOURCEMAP=false
 
# Some apps do not need the benefits of saving a web request, so not inlining the chunk makes for a smoother build process.
INLINE_RUNTIME_CHUNK=false
 
IMAGE_INLINE_SIZE_LIMIT=30000

Code Structure

+-- your-project
|   +-- riant.config.js
|   +-- node_modules
|   +-- package.json
|   +-- public
|   +-- README.md
|   +-- src

Use riant-scripts instead of react-scripts in npm scripts of package.json for start、build and test

  /* package.json */
 
  "scripts": {
-   "start": "react-scripts start",
+   "start": "riant-scripts start",
-   "build": "react-scripts build",
+   "build": "riant-scripts build",
-   "test": "react-scripts test --env=jsdom",
+   "test": "riant-scripts test --env=jsdom",
    "eject": "react-scripts eject"
}

Note: Keep the eject script. That gets run only once for a project, after which you are given full control over the webpack configuration making riant-scripts no longer required.

Start the Dev Server

$ npm start

Build your app

$ npm run build

Readme

Keywords

Package Sidebar

Install

npm i riant-scripts

Weekly Downloads

0

Version

1.3.0

License

MIT

Unpacked Size

58.1 kB

Total Files

26

Last publish

Collaborators

  • fengxinming