美文网首页web收录趣谈前端vue
用webpack4.0撸一个单页/多页脚手架工具(支持jquer

用webpack4.0撸一个单页/多页脚手架工具(支持jquer

作者: 趣谈前端_徐小夕 | 来源:发表于2019-05-09 00:03 被阅读351次

    1.导语

            首先来简单介绍一下webpack:现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个会映射项目所需的每个模块 的依赖图(dependency graph),并生成一个或多个 bundle。webpack4.0出现之后,我们可以不用再引入一个配置文件来打包项目,并且它仍然有着很高的可配置性,可以很好满足我们的需求。
    在开始正文之前,首先先来看看我们要实现的成果:

    • 支持ES6+JQuery+Less/Scss的单页/多页脚手架
    • 支持ES6+React+Less/Scss+Typescript的单页/多页脚手架
    • 支持ES6+Vue+Less/Scss+Typescript的单页/多页脚手架

    github地址:

    基于webpack4.0搭建的脚手架(支持react/vue/typescript/es6+/jquery+less/scss)

    在脚手架的开发过程中我会详细介绍每个插件或者loader的用途以及webpack的核心理念,如有不懂或者有其他更好的想法欢迎交流。
    下面是基于该文章的webpack4.0的思维导图:


    webpack4.png

    2.webpack核心概念

    • 入口:指示 webpack 应该使用哪个模块作为入口起点
    • 输出:告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件
    • loader:让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用
    • 插件:用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量
    • 模式:通过选择 development, production 或 none 之中的一个,来设置 mode 参数,从而进行不同的打包优化
    • 浏览器兼容性:支持所有符合ES5 标准的浏览器(不支持 IE8 及以下版本)
      下面提供官网的打包模型


      webpack@2x.png

    3.支持ES6+JQuery+Less/Scss的单页/多页脚手架

    在实现脚手架之前,假设我们已经创建了目录和package.json文件,接下来先安装webpack相关依赖:

    // 此处建议安装局部依赖,安装全局依赖可能会出现版本问题
    npm install -D webpack webpack-cli
    

    因为项目要支持es6+,我们还需要安装babel相关依赖:

    npm install -D babel-loader @babel/core @babel/preset-env 
    

    这个时候可以开始配置我们的脚手架逻辑了,为了项目结构清晰易于维护,我们建一个build目录专门放webpack构建的脚本,webpack默认的配置文件是webpack.config.js,由于实际项目需要,我们将其拆分为3个文件,分别是webpack通用配置文件webpack.base.js,开发环境配置文件webpack.dev.js以及生产环境配置文件webpack.prod.js。


    image.png

    我们先处理webpack.common.js文件

    const path = require('path');
    const webpack = require('webpack');
    
    module.exports = {
        entry: {
            main: './src/index.js',
        },
        output: {
            path: path.resolve(__dirname, '../dist'),
        },
        module: {
            rules: [
                // 将es6编译成es5
                { 
                    test: /\.jsx?$/,   // ?表示x有0个或一个
                    exclude: /node_modules/,  // 不编译某个目录下的文件
                    include: path.resolve(__dirname, '../src'),  // 只在include包含的目录下进行loader编译
                    use: [
                        "babel-loader",
                    ]
                },
            ]
        }
    }
    

    为了项目后期的开发和维护,我们建立好项目结构:


    image.png

    public目录是事先准备好的html模版,这里就不介绍了,其他目录可根据具体项目进行设置。

    我们还需要一个插件将打包后的文件植入到html模版中并导出到dist目录下,这里使用html-webpack-plugin来实现

    npm install -D html-webpack-plugin
    

    现在webpack.base.js为如下:

    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const template = path.resolve(__dirname, '../public/index.html');
    
    module.exports = {
        entry: {
            main: './src/index.js'
        },
        output: {
            path: path.resolve(__dirname, '../dist')
        },
        module: {
            rules: [
                // 将es6编译成es5
                { 
                    test: /\.jsx?$/,   // ?表示x有0个或一个
                    exclude: /node_modules/,  // 不编译某个目录下的文件
                    include: path.resolve(__dirname, '../src'),  // 只在include包含的目录下进行loader编译
                    use: [
                        "babel-loader",
                    ]
                },
            ]
        },
        plugins: [
            new HtmlWebpackPlugin({
                template,
                filename: 'index.html'
            })
        ]
    }
    

    为了打包项目,我们需要在webpack.prod.js目录下进行配置,此处需要一个模块webpack-merge将wepack基础配置合并进生产配置,我们先来安装一下:

    npm install -D webpack-merge
    

    webpack.prod.js配置如下:

    const merge = require('webpack-merge');
    const base = require('./webpack.base');
    
    module.exports = merge({
        mode: 'production',
        output: {
            filename: 'js/[name]_[contenthash].js',  // 入口和内容hash组成的文件名,也可以是hash
            chunkFilename: 'js/[name]_[contenthash].chunk.js'
        }
    }, base)
    

    然后在package.json里添加执行脚本:

    "scripts": {
        "build": "webpack --config ./build/webpack.prod.js"
      }
    

    webpack默认会找名为webpack.config.js的文件,由于我们将其拆解为prod和dev,所以我们要手动指定webpack执行的文件,添加--config,即可手动指定目录。下面我们开始写一段代码试试吧,在index.js中写入如下es6代码:

    // index.js
    let name = 'xuxi';
    let say = (name) => {
        alert(name)
    };
    say(name);
    

    下面我们执行:

    npm run build
    

    此时我们会看见项目中多了一个dist目录,里面的html也植入了相应的代码,


    image.png

    在浏览器中打开:


    image.png
    ok,第一步完成。
    下一步是支持css,我们先安装如下几个模块:
    npm install --save-dev css-loader style-loader
    

    在webpack.base.js中的module中添加如下代码:

    module: {
            rules: [
                // 将es6编译成es5
                { 
                    test: /\.jsx?$/,   // ?表示x有0个或一个
                    exclude: /node_modules/,  // 不编译某个目录下的文件
                    include: path.resolve(__dirname, '../src'),  // 只在include包含的目录下进行loader编译
                    use: [
                        "babel-loader",
                    ]
                },
                // 加载css
                {
                    test: /\.css$/,
                    use: ['style-loader', 'css-loader'],
                },
            ]
        }
    

    注意,laoder的加载顺序是从下往上,从右往左的,所以配置loader的时候要注意一下顺序。
    此时在styles目录下加入app.css,在js中引入:

    // app.css
    #root {
        background-color: #f0c;
        height: 100px;
    }
    
    // index.js
    import './styles/app.css'
    

    此时打开浏览器,可以看到css生效了:


    image.png

    现在css导入虽然生效了,但是是有js动态创建添加到head里面的,如果后期项目复杂了,将会严重影响项目的加载速度,所以我们这里需要另一个插件,对css进行代码分割,单独生成css文件:

    npm isntall mini-css-extract-plugin -D
    

    根据该插件的官方配置,我们需要把style-loader替换成该插件提供的loader,并配置导出的css文件目录和文件名,为了提高开发环境构建速度,我们只在生产环境分割css:

    // webpack.prod.js
    const merge = require('webpack-merge');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const base = require('./webpack.base');
    
    module.exports = merge({
        mode: 'production',
        output: {
            filename: 'js/[name]_[contenthash].js',  // 入口和内容hash组成的文件名,也可以是hash
            chunkFilename: 'js/[name]_[contenthash].chunk.js'
        },
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: [  // loader解析的顺序是从下到上,从右到左的顺序
                        {
                            loader: MiniCssExtractPlugin.loader,
                            options: {
                                filename: '[name].css',
                                chunkFilename: '[name].css',
                                publicPath: '../'   //****最后打包的时候替换引入文件路径
                            },
                        },
                        // 'style-loader',  使用MiniCssExtractPlugin时就不能使用style-loader了
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 2   //该方式可以让@import引入的css文件再次执行一边css打包loader
                            }
                        },
                    ]
                }
            ]
        },
        plugins: [
            new MiniCssExtractPlugin({
                // Options similar to the same options in webpackOptions.output
                // both options are optional
                filename: 'css/[name]_[hash].css',
                chunkFilename: 'css/[name]_[hash].chunk.css',
              }),
        ]
    }, base)
    

    由于我们在dev和prod环境的css-loader不一样,所以我们将base的css-loader配置删除,移到dev下

    // webpack.dev.js
    const base = require('./webpack.base');
    const merge = require('webpack-merge');
    const webpack = require('webpack');
    
    module.exports = merge({
        mode: 'development',
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: [  // loader解析的顺序是从下到上,从右到左的顺序
                        'style-loader',  //使用MiniCssExtractPlugin时就不能使用style-loader了
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 2   //该方式可以让@import引入的css文件再次执行一边css打包loader
                            }
                        },
                    ]
                }
            ]
        },
        output: {
            filename: '[name].js',
            chunkFilename: '[name].js',
        }
    }, base)
    

    ok,此时我们就完成一个基本的打包es6,css的模块打包工具,为了支持更高的es6+语法,我们配置.babelrc文件,以及安装相应的npm包:

    npm install @babel/polyfill core-js -D
    

    .babelrc文件如下:

    {
        "presets": [
            [
                "@babel/preset-env",   // 将ES6语法转换为es5
                {
                    "useBuiltIns": "usage",    // 只编译需要编译的代码
                    "corejs": "3.0.1",
                }
            ],
          ]
    }
    

    我们会看到babelrc文件里面有"useBuiltIns": "usage", 这个配置涉及到一个关于webpack打包的高级用法,tree-shaking。

    tree-shaking:用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块语法的 静态结构 特性,例如 importexport。这个术语和概念实际上是由 ES2015 模块打包工具 rollup 普及起来的。

    我们通过使用tree-shaking,可以极大的减少代码的体积,对于提高打包性能很有帮助。为了使tree-shaking能生效,我们还要在webpack配置文件中开启:

    // webpack.base.js
    optimization: {
            usedExports: true
        }
    

    还有一个问题,由于tree-shaking是基于import 和export的,当我们用import引入css文件时,是没有导出的,所以我们需要配置忽略css文件的tree-shaking,在package.json中添加如下配置:

    // package.json
    "sideEffects": [
        "*.css",
        "*.less"
      ],
    

    在打包的过程中,每次执行打包都会新建一个打包文件,我们想要每次打包之前都清除上一次打包的文件怎么办呢?我们可以使用clean-webpack-plugin来实现,首先先安装,然后具体配置如下:

    // webpack.prod.js
    plugins: [
            new CleanWebpackPlugin()
        ],
    

    该插件会默认清除dist目录下的打包文件。
    接下来我们安装jquery:

    npm install jquery -S
    

    在index.js引入并使用:

    import $ from 'jquery';
    import './styles/app.css'
    
    console.log($('#root').html('hello world'));
    

    执行npm run build后,我们在浏览器中打开,即可看到jq的作用:


    image.png

    但是我们看dist目录下的js文件,发现jquery和业务代码都打包进一个页面了,这样会导致当业务复杂时,整个页面代码会非常大,我们进一步做优化,即js代码分割。
    根据webpack官网的方案,我们只需要进行简单的配置,便可以进行对js代码分割:

    //webpack.base.js
    optimization: {
            splitChunks: {
                chunks: 'all',
                // chunks: 'async', // async表示只对异步代码进行分割
                minSize: 30000,  // 当超过指定大小时做代码分割
                // maxSize: 200000,  // 当大于最大尺寸时对代码进行二次分割
                minChunks: 1,
                maxAsyncRequests: 5,
                maxInitialRequests: 3,
                automaticNameDelimiter: '_',
                name: true,
                cacheGroups: {  // 缓存组:如果满足vendor的条件,就按vender打包,否则按default打包
                    vendors: {
                        test: /[\\/]node_modules[\\/]/,
                        priority: -10, // 权重越大,打包优先级越高
                        // filename: 'js/vender.js'  //将代码打包成名为vender.js的文件
                        name: 'vender'
                    },
                    default: {
                        minChunks: 2,
                        priority: -20,
                        name: 'common',
                        // filename: 'js/common.js',
                        reuseExistingChunk: true // 是否复用已经打包过的代码
                    }
                }
            },
            usedExports: true
        }
    

    由于篇幅限制,splitChunks的具体配置我通过注释写出来了,如果想了解更详细的配置,后面大家可以去webpack官网查看。此时执行npm run build,我们可以看到代码已经进行了分割:


    image.png

    当然只满足与css和js的打包还远远不够,我们项目中还会用到各种图片,字体图标,css预编译语言如less或者scss,由于这部分的安装比较简单,我们直接上代码。
    首先安装相关依赖:

    npm install url-loader file-loader less less-loader
    

    此时我们webpack.base.js中module变为:

    module: {
            rules: [
                // 将es6编译成es5
                { 
                    test: /\.jsx?$/,   // ?表示x有0个或一个
                    exclude: /node_modules/,  // 不编译某个目录下的文件
                    include: path.resolve(__dirname, '../src'),  // 只在include包含的目录下进行loader编译
                    use: [
                        "babel-loader",
                    ]
                },
                // 加载解析文件资源
                {
                    test: /\.(jpg|png|gif)$/,
                    use: {
                        loader: 'url-loader', // 和file-loader功能相同,但更智能
                        options: {
                            // 配置打包后的文件名,具体可看webpack的file-loader文档
                            name: '[name].[ext]?[hash]',
                            outputPath: 'images/',
                            limit: 4096 // 当图片大小大于4k时将以文件形式输出,否则以base64输出
                        }
                    }
                },
                // 引入字体,svg等文件
                {
                    test: /\.(eot|ttf|svg)$/,
                    use: {
                        loader: 'file-loader'
                    }
                }
            ]
        },
    

    为了支持less,我们修改一下dev和prod文件:

    // webpack.dev.js
    module: {
            rules: [
                {
                    test: /\.(css|less)$/,
                    use: [  // loader解析的顺序是从下到上,从右到左的顺序
                        'style-loader',  //使用MiniCssExtractPlugin时就不能使用style-loader了
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 2   //该方式可以让@import引入的css文件再次执行一边css打包loader
                            }
                        },
                        'less-loader',
                    ]
                }
            ]
        }
    
    //  webpack.prod.js
    module: {
            rules: [
                {
                    test: /\.(css|less)$/,
                    use: [  // loader解析的顺序是从下到上,从右到左的顺序
                        {
                            loader: MiniCssExtractPlugin.loader,
                            options: {
                                filename: '[name].css',
                                chunkFilename: '[name].css',
                                publicPath: '../'   //****最后打包的时候替换引入文件路径
                            },
                        },
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 2   //该方式可以让@import引入的css文件再次执行一边css打包loader
                            }
                        },
                        'less-loader'
                    ]
                }
            ]
        }
    

    我们写一段less代码试试:

    body {
        #root {
            background-color: #000;
            color: #fff;
        }
    }
    

    我们执行build之后在浏览器打开看看效果:


    image.png

    ok,至此,我们第一步也是最重要的一步已经完成了,由于开发项目的时候不可能每次改动代码都构建一次,这样时间成本太大了,我们想要实时看到改变的内容,这个时候就要用webpack4.0提供的devServer了,它使得我们项目可以支持热更新和热模块替换,我们需要在开发环境下对其进行配置,具体如下:
    首先安装开发服务器模块:

    npm install webpack-dev-server -D
    

    接着配置dev文件:

    webpack.dev.js
    const base = require('./webpack.base');
    const merge = require('webpack-merge');
    const webpack = require('webpack');
    
    module.exports = merge({
        mode: 'development',
        module: {
            rules: [
                {
                    test: /\.(css|less)$/,
                    use: [  // loader解析的顺序是从下到上,从右到左的顺序
                        'style-loader',  //使用MiniCssExtractPlugin时就不能使用style-loader了
                        'vue-style-loader',
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 2   //该方式可以让@import引入的css文件再次执行一边css打包loader
                            }
                        },
                        // 'sass-loader',
                        'less-loader',
                        'postcss-loader',
                    ]
                }
            ]
        },
        // 服务器配置
        devServer: {
            port: '8081',
            // 当使用 HTML5 History API 时,任意的 404 响应都可能需要被替代为 index.html
            historyApiFallback: true, // 解决单页面路由问题,
            contentBase: '../dist',
            open: true,  //自动打开浏览器
            hot: true,  // 开启热替换, css代码跟新不刷新页面
            // hotOnly: true 开启后只有手动配置才能更新,即使hot为true也不刷新浏览器
            proxy: {
                index: '', // 将index设置为空,可以对根路径进行转发
                'api/get': 'xxxx.com/api', // 第一种方式,直接代理到api路径
                'api/vue': {  // 第二种方式,在路径需要临时替换时使用
                    target: 'xxxx.com/api',
                    pathRewrite: {
                        'head': 'demo'  //此时访问head路径将被代理到demo下
                    },
                    secure: false,  //对https请求的配置,false为支持https
                    changeOrigin: true  //做代理分发时允许访问其他网站,突破网站限制,建议在开发环境使用
                },
    
            }
        },
        plugins: [
            new webpack.HotModuleReplacementPlugin()
        ],
        output: {
            filename: '[name].js',
            chunkFilename: '[name].js',
        }
    }, base)
    

    以上代码中,要使用热模块替换,我们需要用到webpack自己集成的插件webpack.HotModuleReplacementPlugin,在devServer中,我们还可以设置开发环境中的代理proxy,这已经是目前开发的默认模式了,代码中一些属性的用法和含义我都做了注释,如果大家有兴趣,可以查看webpack原版官方文档,那里有更详细的配置信息。
    我们再来修改package.json,添加开发环境的运行指令:

    // 在script里面添加
    "start": "webpack-dev-server --config ./build/webpack.dev.js",
    

    我们执行 npm start,此时会自动打开浏览器,运行我们的项目。

    到此,我们基本的一个支持ES6+Less/css+JQuery的单页应用打包工具已经做好了,当然这只是基础,后面的多页应用,vue/react/typescript都是在这个基础上构建的,让我们拭目以待。

    多页面应用:

    我们开发多页面应用还是需要用到之前使用的html-webpack-plugin插件,此时我们需要定义多个入口:

    // webpack.base.js
    entry: {
            main: './src/index.js',
            about: './src/about.js'
        }
    
    plugins: [
    new HtmlWebpackPlugin(
            {
                template,
                title: 'webpack打包但单应用',
                chunks: ['vender', 'main'],
                filename: 'index.html'
            }
        ),
        new HtmlWebpackPlugin(
            {
                template,
                title: '关于我们',
                chunks: ['vender', 'about'],
                filename: 'about.html'
            }
        ),
    ]
    

    template是我们定义的public下的html路径,title是我们要植入html模版中的titl标签中的内容,我们在index.html中这么使用:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title><%= htmlWebpackPlugin.options.title %></title>
        <link rel="shortcut icon" href="./favicon.ico">
    </head>
    <body>
        <div id="root"></div>
    </body>
    </html>
    

            这样,webpack配置的title就可以动态的添加到html页面中了,这里我要说一下在new HtmlWebpackPlugin中我们添加了chunks数组,这个数组就是我们要打包进页面的js,main和about分别代表入口的名字,vender就是我们定义optimization时里面cacheGroups属性值中vendors中定义的name,当代码超过30000b时就会生成vender.js文件。
            此时我们执行npm run build,打包结束后将会生成2个html页面,对应的文件依赖也会引入,在浏览器中打开,亲测有效~


    image.png

    这样,一个基本的多页面打包工具就开发完成了,不过还有几点优化:

    1. 代码压缩,
    2. 第三方模块懒编译,我们可以使用webpack提供的dll技术做优化
    3. pwa技术引入
      下面分别是相关实现:
      1.代码压缩,我们使用terser-webpack-plugin压缩js,用optimize-css-assets-webpack-plugin压缩css
    npm install terser-webpack-plugin optimize-css-assets-webpack-plugin -D
    

    我们在webpack.prod.js中添加一下配置:

    // 导入模块
    // 压缩css
    const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    // 压缩js
    const TerserPlugin = require('terser-webpack-plugin');
    
    // 配置module.exports,添加配置如下
    optimization: {
            minimizer: [
                new TerserPlugin({   // 压缩js代码
                    cache: true,   // 启用文件缓存
                    parallel: true,  // 使用多进程并行执行任务来提高构建效率
                    sourceMap: true,  // 将错误消息位置映射到模块
                    terserOptions: {
                        drop_console: true,  // 打包时剔除所有console.log
                        drop_debugger: true  // 打包时剔除所有debugger
                    }
                }), 
                new OptimizeCSSAssetsPlugin({})]  // 压缩css代码
        },
    
    1. pwa:渐进式网络应用程序(progressive web application - PWA),是一种可以提供类似于native app(原生应用程序) 体验的 web app(网络应用程序)。首先我们安装依赖:
    npm install workbox-webpack-plugin --save-dev
    

    在需要做pwa的页面里加入如下脚本启动:

    if ('serviceWorker' in navigator) {  window.addEventListener('load', () => {
                navigator.serviceWorker.register('/service-worker.js').then(registration => {
                    console.log('SW registered: ', registration);
                }).catch(registrationError => {
                    console.log('SW registration failed: ', registrationError);
                    });
                });
     }
    
    1. dll文件优化打包速度
      关于dll问题,我们可以在官网上查询具体的使用方法,这里就不具体说明了。

    至此,我们关于开发基于ES6+JQuery+Less/Scss的单页/多页脚手架就告于段落了,下面我们来集成对react/vue/typescript的支持。

    1.支持react

    我们首先安装一个babel模块:

    npm install --save-dev @babel/preset-react
    

    然后在.babelrc中加入如下配置:

    {
      "presets": [
        [
          "@babel/preset-react",
          {
            "pragma": "dom", // default pragma is React.createElement
            "pragmaFrag": "DomFrag", // default is React.Fragment
            "throwIfNamespace": false // defaults to true
          }
        ]
      ]
    }
    

    然后在index.js中写入一段react代码:

    import React, {Component} from 'react'
    import ReactDOM from 'react-dom'
    
    class App extends Component {
        render() {
            return <div>react frame content.</div>
        }
    }
    
    ReactDOM.render(<App />, document.getElementById('root'));
    

    打包后即可在浏览器中看到效果。

    2.支持vue

    首先先安装对应npm包:

    npm install -D vue-loader vue-template-compiler
    

    之后在webpack的配置文件中写入如下代码:

    // webpack.base.js
    const VueLoaderPlugin = require('vue-loader/lib/plugin')
    
    module.exports = {
      module: {
        rules: [
          // ... other rules
          {
            test: /\.vue$/,
            loader: 'vue-loader'
          }
        ]
      },
      plugins: [
        // make sure to include the plugin!
        new VueLoaderPlugin()
      ]
    }
    

    如果要想解析.vue文件中的style,我们需要使用vue-style-loader模块,安装之后将其添加到loder中即可。
    接下来我们写个简单的vue试一下吧:

    <template>
      <div class="example">
          {{ msg }}
          <img src="~/images/logo.png" />
          <img :src="imgSrc" />
      </div>
    </template>
    
    <script>
    import Logo from 'images/logo.png';
    import 'css/common.css';
    
    export default {
      data () {
        return {
          msg: 'Hello world!单独的',
          imgSrc: Logo
        }
      }
    }
    </script>
    
    <style lang="less">
    .example {
      color: red;
      img {
          border: 2px solid #000;
      }
    }
    </style>
    

    运行dev在浏览器中即可看到效果。
    值得注意的是vue文件中引入资源的问题,使用相对路径会有问题,这里我们可以使用~/images/logo.png的方式或者require的方式来引入图片。

    3.支持typescript

    这里我们使用awesome-typescript-loader来编译typescript文件,也是官方推荐的一个加载器:

    npm install awesome-typescript-loader --save-dev
    

    然后我们在webpack的配置文件base中,在module的rules里加入如下代码:

    {
            test: /\.tsx?$/,
            loader: 'awesome-typescript-loader'
          }
    

    最后一步,添加tsconfig.json文件:

    {
        "compilerOptions": {
            "noImplicitAny": true,
            "removeComments": true
        },
        "awesomeTypescriptLoaderOptions": {
            /* ... */
        }
    }
    

    该文件有很多灵活的配置项,大家如果想了解更多可以去typescript官网上查看相关文档。
    至此,所有的配置都完成了,是不是很累?哈哈,当然脚手架中还存在一些优化的地方,欢迎大家可以一起完善。

    未完成的优化点:
    • vue文件内部style无法独立抽出样式,只能通过引入css文件的方式加载样式
    • 公用css文件问题:多页面打包时,如果都引入了同一个css,无法服用这个css,希望能将这个css文件作为一个公共模块单独引用

    相关推荐:

    相关文章

      网友评论

        本文标题:用webpack4.0撸一个单页/多页脚手架工具(支持jquer

        本文链接:https://www.haomeiwen.com/subject/ajnjoqtx.html