相关文章推荐

给webpack配置eslint

eslint-config-react-app 此包包含Create React App使用的可共享 ESLint 配置。 npm link

yarn add -D 
eslint-config-react-app 
@typescript-eslint/eslint-plugin@^4.0.0 
@typescript-eslint/parser@^4.0.0 
babel-eslint@^10.0.0 
eslint@^7.5.0 
eslint-plugin-flowtype@^5.2.0 
eslint-plugin-import@^2.22.0 
eslint-plugin-jsx-a11y@^6.3.1 
eslint-plugin-react@^7.20.3 
eslint-plugin-react-hooks@^4.0.8
+ .eslintrc.js
module.exports = {
  //继承 eslint-config-react-app这个里面包含create react app的eslint配置
  "extends": "react-app",
  rules: {
    // jsx使用 react
    'react/jsx-uses-react': [2],
    // 提示要在 JSX 文件里手动引入 React
    'react/react-in-jsx-scope': [2],
    'no-console': [0]

webpack可以感知到eslint的配置,从而在编译的过程中提示报错信息

yarn add eslint-webpack-plugin -D
webpack/config.js
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
  // ...
  plugins: [new ESLintPlugin({
    extensions: ['.js', '.jsx']  //不加就不会去检测.jsx文件了
  // ...

在没加eslint-webpack-plugin之前虽然我们发现在编辑器中eslint给我们报错了,但是在我们运行yarn build的时候他还是可以编译成功的。如下图

下面我们来看看加完之后的情况,这个时候,不仅eslint报错了webpack构建的时候也会在控制台报错,这样就很好地使用了eslint

用babel-loader打包TypeScript

yarn add @babel/preset-typescript -D

babel 官网

webpack.config.js
test: /\.[tj]sx?$/,
presets: [['@babel/preset-typescript']]

添加一个test.tsx,并且在index.js中引入,以下结果编译成功。

让eslint支持TypeScript

eslint支持ts,添加相关的配置。

yarn add eslint-config-airbnb-typescript @types/react -D
.eslintrc.js
 //覆盖之前的配置(检测ts代码)
  overrides: [{
    files: ['*.ts', '*.tsx'],
    parserOptions: {
      project: './tsconfig.json',
    extends: ['airbnb-typescript'],
    rules: {
      '@typescript-eslint/object-curly-spacing': [0],
      'import/prefer-default-export': [0],
      'no-console': [0],
      'import/extensions': [0]

我们运行yarn build发现此时编译还是可以成功的。

webpack.config.js 添加'.ts' '.tsx'
plugins: [new ESLintPlugin({
    extensions: ['.js', '.jsx', '.ts', '.tsx']  //不加就不会去检测.jsx文件了

修改之后的效果

用babel-loader打包tsx

生成tsconfig.json文件。

npx tsc --init
 "jsx": "react", // Specify JS
 "strict": false, // 关闭严格模式  
  "noImplicitAny": true,  //没有隐式的any

同样我们编写tsx-demo.tsx文件在index.js中引入进行测试。

CRLF 是什么?

一、LF和CRLF是什么

  • CRLF 是 carriage return line feed 的缩写,中文意思是回车换行。
  • LF 是 line feed 的缩写,中文意思也是换行。
  • 它们都是文本换行的方式。
  • 二、LF和CRLF区别

  • CRLF: "\r\n", windows系统环境下的换行方式
  • LF: "\n", Linux系统环境下的换行方式
  • 让js和ts支持@alias

    js 支持
    webpack.config.js
    const path = require('path')
    resolve: {
        alias: {
          '@': path.join(__dirname, './src/')
    
    ts 支持
    tsconfig.json 添加
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@/*": [
            "src/*"
    

    引入代码测试

    让webpack支持scss

    sass-loader npm

    yarn add sass-loader sass style-loader css-loader -D
    
    module.exports = {
      module: {
        rules: [
            test: /\.s[ac]ss$/i,
            //执行顺序从右到左
            use: [
              // Creates `style` nodes from JS strings
              "style-loader",
              // Translates CSS into CommonJS
              "css-loader",
              // Compiles Sass to CSS
              "sass-loader",
    
  • sass-loader npm点进去里面有具体的配置。
  • Vue-loader这个是Vue-loader的官方文档
  • scss自动import全局文件

    test: /\.s[ac]ss$/i, use: [ // Creates `style` nodes from JS strings "style-loader", // Translates CSS into CommonJS "css-loader", // Compiles Sass to CSS loader: "sass-loader", options: { //需要添加的字符串 additionalData: ` @import '@/var.scss'; sassOptions: { includePaths: [__dirname] //基于当前目录

    scss分享变量给js

    可以让项目中用到的css变量用同一份jsscss共同维护一份变量。

    + scss-export.scss
    :export {
      border-color: $body-color;
    
    index.js
    import vars from './scss-export.scss';
    console.log(vars)
    

    webpack支持less文件

    less-loader npm

    yarn add less less-loader -D
    
    @import './_var.less';
    body{
      color: @color;
    
    webpack.config.js
        test: /\.less$/i,
        use: [
            loader: "style-loader",
            loader: "css-loader",
            options: {
              modules: {
                compileType: 'icss',
            loader: "less-loader",
            options: {
              additionalData: `
                    @import './_var.less';
    

    less分享给js

    _var.less
    @color: pink;
    :export{
      color: @color;
    
    index.js
    import vars from './_var.less';
    console.log(vars)
    

    对比scss 和less

    要选的话就选scss

    stylus文件

    stylus npm

    style.stylus
    color = black;
    //变量分享给js
    :export{
      color: color
    
    yarn add stylus stylus-loader -D
    
    webpack.config.js
        test: /\.styl$/,
        use: [
            loader: "style-loader",
            loader: "css-loader",
            options: {
              modules: {
                compileType: 'icss',
            loader: "stylus-loader",
            options: {
              stylusOptions: {
                import: [path.resolve(__dirname, "src/_var.styl")]
    

    webpack config 重构

    webpack.config.js
    const cssLoaders = (...loaders) => [
      // Creates `style` nodes from JS strings
      "style-loader",
      // Translates CSS into CommonJS
        loader: 'css-loader',
        options: {
          modules: {
            compileType: 'icss',
      ...loaders
    

    生产页面单独提取css文件

    mini-css-extract-plugin webpack文档

    yarn add mini-css-extract-plugin -D
    
    webpack.config.js
    const cssLoaders = (...loaders) => [
      // Creates `style` nodes from JS strings
      mode === 'production' ? MiniCssExtractPlugin.loader : "style-loader",
      // Translates CSS into CommonJS
        loader: 'css-loader',
        options: {
          modules: {
            compileType: 'icss',
      ...loaders
    plugins: [
        new ESLintPlugin({
          extensions: ['.js', '.jsx', '.ts', '.tsx']  //不加就不会去检测.jsx文件了
        mode === 'production' && new MiniCssExtractPlugin({
          filename: '[name].[contenthash].css'
    ].filter(Boolean)
    

    自动生成HTML页面

    html-webpack-plugin npm

    yarn add html-webpack-plugin -D
    
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    module.exports = {
      entry: 'index.js',
      output: {
        filename: '[name].[contenthash].js'
      plugins: [
        new HtmlWebpackPlugin()
    

    webpack优化 单独打包runtime

    optimization: {
        runtimeChunk: 'single',  //运行时文件单独打包
    

    为什么要单独打包runtime

  • runtime里面的文件是webpack为了运行main.js文件所要依赖的文件。
  • 如果不单独打包,如果我们修改了webpack的配置之后mian.js里面的内容就会发生变化,用户的缓存就会失效,如果单独打包的话当修改完webpack的配置之后只,如果我们没有改变main.js里面的内容的话,就不会重新打包main.js的内容,这样就可以节省宽带,提高用户访问页面的速度。
  • webpack优化 用splitChunks将node依赖单独打包

    在编译的时候要缓存React等类库文件。

    webpack优化 固定modules

    webpack.config.js
    optimization: {
    moduleIds: 'deterministic',
    runtimeChunk: 'single',  //运行时文件单独打包
    splitChunks: {
      cacheGroups: {
        vendor: {
          priority: 10,
          minSize: 0, /* 如果不写 0,由于 React 文件尺寸太小,会直接跳过 */
          test: /[\\/]node_modules[\\/]/, // 为了匹配 /node_modules/ 或 \node_modules\
          name: 'vendors', // 文件名
          chunks: 'all',  // all 表示同步加载和异步加载,async 表示异步加载,initial 表示同步加载
          // 这三行的整体意思就是把两种加载方式的来自 node_modules 目录的文件打包为 vendors.xxx.js
          // 其中 vendors 是第三方的意思
    

    之后再运行yarn build可以看见引入了三个js文件

    optimizationmoduleids

    webpack 多页面

    webpack.config.js
    entry: {
        main: './src/index.js',
        admin: './src/admin.js'
    plugins: [
        new HtmlWebpackPlugin({
          filename: 'index.html',
          chunks: ['main']
        new HtmlWebpackPlugin({
          filename: 'admin.html',
          chunks: ['admin']
    

    webpack优化 common插件

    如果共有的文件就打包成一个文件,如果两个入口都同时引用了一个文件,

     optimization: {
        runtimeChunk: 'single',  //运行时文件单独打包
        splitChunks: {
          cacheGroups: {
            common: {
              priority: 5,
              minSize: 0,
              minChunks: 2, //同一个文件至少被多少个入口引用了
              chunks: 'all',
              name: 'common'
    
  • runtime 为了运行mian.js所要提供的代码。
  • node_modules venders 全局的
  • common模块间的 admin.js 和 index.js
  • self自身的
  • 看这个打包之后页面引入js的顺序

    无限多页面的实现思路

    webpack.config.js
    let entry = {}
    let outputHtml = []
    var pages = fs.readdirSync(path.resolve(__dirname, pagesDir))
    pages.forEach((item)=>{
      let name = item.replace('.js', '')
      entry[name] = `${pagesDir}${item}`
      outputHtml.push(new HtmlWebpackPlugin({
        filename: `${name}.html`,
        chunks: [name]
    只需要把这两个参数弄成动态生成的即可满足要求。测试之后大功告成!!!

    最后附上源代码连接 github

    Webpack入门到精通 一(AST、Babel、依赖)

    Webpack入门到精通 二(核心原理)

    Webpack入门到精通 三(Loader原理)

    Webpack入门到精通 四(Plugin原理)

    Webpack入门到精通 五(常用配置)

     
    推荐文章