Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

专题12: 配置loader如:ts、babel、less|sass #54

Open
luoxue-victor opened this issue Nov 20, 2019 · 0 comments
Open

专题12: 配置loader如:ts、babel、less|sass #54

luoxue-victor opened this issue Nov 20, 2019 · 0 comments
Labels
webpack 专题 一些系列专题

Comments

@luoxue-victor
Copy link
Owner

luoxue-victor commented Nov 20, 2019

本章提要:

  • 配置 babel
  • 使用 babel 配置 ts
  • ts 静态类型检查
  • 友好错误提示插件
  • 配置样式,style,css、less、sass、postcss 等
  • 编译前后 css 对比
  • postcss 配置
  • 配置 autoprefixer
  • 开启 source map

目录

增加以下文件

// 配置目录
|-- config
  |-- babelLoader.js  // babel-loader 配置
  |-- ForkTsChecker.js // ts 静态检查
  |-- FriendlyErrorsWebpackPlugin.js // 友好错误提示
  |-- style
// 开发目录
|-- src
  |-- style
    |-- app.css
    |-- index.less      // 测试 less
    |-- index.scss      // 测试 sass
    |-- index.postcss   // 测试 postcss
  |-- ts
    |-- index.ts        // 测试 ts
|-- babel.js
|-- postcss.config.js   // postcss 配置
|-- tsconfig.json       // ts 配置
// 打包后的目录
|--dist
  |-- app.bundle.js
  |-- app.css
  |-- index.html

配置 babel

config/babelLoader.js

module.exports = (config, resolve) => {
  const baseRule = config.module.rule('js').test(/.js|.tsx?$/);
  const babelPath = resolve('babel.js');
  const babelConf = require(babelPath);
  const version = require(resolve('node_modules/@babel/core/package.json'))
    .version;
  return () => {
    baseRule
      .use('babel')
      .loader(require.resolve('babel-loader'))
      .options(babelConf({ version }));
  };
};

使用 babel 配置 ts

这里我们使用 babel 插件 @babel/preset-typescriptts 转成 js,并使用 ForkTsCheckerWebpackPluginForkTsCheckerNotifierWebpackPlugin 插件进行错误提示。

babel.js

module.exports = function(api) {
  return {
    presets: [
      [
        '@babel/preset-env',
        {
          targets: {
            chrome: 59,
            edge: 13,
            firefox: 50,
            safari: 8
          }
        }
      ],
      [
        '@babel/preset-typescript',
        {
          allExtensions: true
        }
      ]
    ],
    plugins: [
      '@babel/plugin-transform-typescript',
      'transform-class-properties',
      '@babel/proposal-object-rest-spread'
    ]
  };
};

ts 静态类型检查

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const ForkTsCheckerNotifierWebpackPlugin = require('fork-ts-checker-notifier-webpack-plugin');

module.exports = (config, resolve) => {
  return () => {
    config.plugin('ts-fork').use(ForkTsCheckerWebpackPlugin, [
      {
        // 将async设为false,可以阻止Webpack的emit以等待类型检查器/linter,并向Webpack的编译添加错误。
        async: false
      }
    ]);
    // 将TypeScript类型检查错误以弹框提示
    // 如果fork-ts-checker-webpack-plugin的async为false时可以不用
    // 否则建议使用,以方便发现错误
    config.plugin('ts-notifier').use(ForkTsCheckerNotifierWebpackPlugin, [
      {
        title: 'TypeScript',
        excludeWarnings: true,
        skipSuccessful: true
      }
    ]);
  };
};

友好错误提示

config/FriendlyErrorsWebpackPlugin.js

const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');

module.exports = (config, resolve) => {
  return () => {
    config.plugin('error').use(FriendlyErrorsWebpackPlugin);
  };
};

配置 style,css、less、sass、postcss 等

module.exports = (config, resolve) => {
  const createCSSRule = (lang, test, loader, options = {}) => {
    const baseRule = config.module.rule(lang).test(test);
    const normalRule = baseRule.oneOf('normal');
    normalRule
      .use('extract-css-loader')
      .loader(require('mini-css-extract-plugin').loader)
      .options({
        hmr: process.env.NODE_ENV === 'development',
        publicPath: '/'
      });
    normalRule
      .use('css-loader')
      .loader(require.resolve('css-loader'))
      .options({});
    normalRule.use('postcss-loader').loader(require.resolve('postcss-loader'));
    if (loader) {
      const rs = require.resolve(loader);
      normalRule
        .use(loader)
        .loader(rs)
        .options(options);
    }
  };

  return () => {
    createCSSRule('css', /\.css$/, 'css-loader', {});
    createCSSRule('less', /\.less$/, 'less-loader', {});
    createCSSRule('scss', /\.scss$/, 'sass-loader', {});
    createCSSRule('postcss', /\.p(ost)?css$/);
  };
};

postcss 配置

module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      unitToConvert: 'px',
      viewportWidth: 750,
      unitPrecision: 5,
      propList: ['*'],
      viewportUnit: 'vw',
      fontViewportUnit: 'vw',
      selectorBlackList: [],
      minPixelValue: 1,
      mediaQuery: false,
      replace: true,
      exclude: [],
      landscape: false,
      landscapeUnit: 'vw',
      landscapeWidth: 568
    }
  }
};

编译后 css 对比

src/style/index.less

/* index.less */
.test {
  width: 300px;
}

dist/app.css

/* index.css */
.test {
  width: 26.66667vw;
  height: 26.66667vw;
  color: red;
  background-color: orange;
}
/* app.css */
.test {
  font-size: 8vw;
}
/* index.less */
.test {
  width: 40vw;
}

/* index.scss */
.test {
  height: 40vw;
}
/* index.postcss */
.test {
  background: green;
  height: 26.66667vw;
}

配置 autoprefixer

自动添加 css 前缀

postcss.config.js

module.exports = {
  plugins: {
    autoprefixer: {
      overrideBrowserslist: [
        '> 1%',
        'last 3 versions',
        'iOS >= 8',
        'Android >= 4',
        'Chrome >= 40'
      ]
    }
  }
};

转换前

/* index.css */
.test {
  width: 200px;
  height: 200px;
  color: red;
  display: flex;
  background-color: orange;
}

转换后

/* index.css */
.test {
  width: 26.66667vw;
  height: 26.66667vw;
  color: red;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  background-color: orange;
}

开启 source map

config.devtool('cheap-source-map');
|--dist
  |-- app.bundle.js
  |-- app.bundle.js.map
  |-- app.css
  |-- app.css.map
  |-- index.html

在源文件下会有一行注释,证明开启了 sourcemap

/*# sourceMappingURL=app.css.map*/

@luoxue-victor luoxue-victor added 专题 一些系列专题 webpack labels Nov 20, 2019
@luoxue-victor luoxue-victor changed the title 专题12: 配置ts、babel、less|sass 专题12: 配置loader如:ts、babel、less|sass Nov 20, 2019
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
webpack 专题 一些系列专题
Projects
None yet
Development

No branches or pull requests

1 participant