GVKun编程网logo

import被webpack编译成了啥?(import webpack)

14

这篇文章主要围绕import被webpack编译成了啥?和importwebpack展开,旨在为您提供一份详细的参考资料。我们将全面介绍import被webpack编译成了啥?的优缺点,解答impor

这篇文章主要围绕import被webpack编译成了啥?import webpack展开,旨在为您提供一份详细的参考资料。我们将全面介绍import被webpack编译成了啥?的优缺点,解答import webpack的相关问题,同时也会为您带来.tsx webpack编译失败:意外的令牌<、Dynamic imports with webpack、ES6通过babel转码使用webpack使用import关键字、npm+babel+webpack解决不能import问题的实用方法。

本文目录一览:

import被webpack编译成了啥?(import webpack)

import被webpack编译成了啥?(import webpack)

import 被webpack 编译成了啥?

我们知道,webpack 打包过程如下:

  • 合并webpack.config.js和命令行传递的参数,形成最终的配置
  • 解析配置,得到entry入口
  • 读取入口文件内容,通过@babel/parse将入口内容(code)转换成ast
  • 通过@babel/traverse遍历ast得到模块的各个依赖
  • 通过@babel/core(实际的转换工作是由@babel/preset-env来完成的)将ast转换成es5 code
  • 通过循环伪递归的方式拿到所有模块的所有依赖并都转换成es5

那么,问题来了。

问题:import moduleName from 'xxModule’和import(‘xxModule’)经过webpack编译打包后最终变成了什么?在浏览器中是怎么运行的?

答案:

  • import经过webpack打包以后变成一些Map对象,key为模块路径,value为模块的可执行函数;
  • 当然其中的异步方法(import(‘xxModule’))比较特殊一些,它会单独打成一个包,采用动态加载的方式。
    具体过程:当用户触发其加载的动作时,会动态的在head标签中创建一个script标签,然后发送一个http请求,加载模块,模块加载完成以后自动执行其中的代码,主要的工作有两个,更改缓存中模块的状态,另一个就是执行模块代码。(webpack4)

没看懂?继续往下看解析

分析:

  1. 初始化项目

    在这里插入图片描述

    执行命令

    npm init -y
    npm i webpack webpack-cli -D
    

    webpack.config.js文件:

    const path = require('path')
    
    module.exports = {
      entry: './src/index.js',
      // 为了利于分析打包后的代码,这里选择开发模式
      mode: 'development',
      output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'main.js'
      }
    }
    

    src/index.js 文件:

    /**
     * 入口文件,引入 print 方法,并执行
     * 定义了一个 button 方法,为页面添加一个按钮,并为按钮设置了一个 onclick 事件,负责动态引入一个文件
     */
    import { print } from './num.js'
    
    print()
    
    function button () {
      const button = document.createElement('button')
      const text = document.createTextNode('click me')
      button.appendChild(text)
      button.onclick = e => import('./info.js').then(res => {
        console.log(res.log)
      })
      return button
    }
    
    document.body.appendChild(button())
    

    src/num.js 文件:

    export function print () {
      console.log('我是 num.js 的 print 方法')
    }
    

    src/num.js 文件:

    export const log = "log info"
    

打包@H_301_88@

执行命令

npx webpack

在这里插入图片描述

会看到多了一个 dist 目录,且看输出结果,main.js是我们在webpack.config.js中配置的输出的文件名,但是src_info_js.main.js呢?这是什么????

模版文件@H_301_88@

新建/dist/index.html文件,并引入打包后的main.js

<!DOCTYPE html>
<html lang="en">
<head>
  <Meta charset="UTF-8">
  <Meta http-equiv="X-UA-Compatible" content="IE=edge">
  <Meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src = "./main.js"></script>
</body>
</html>

在浏览器打开 index.html@H_301_88@

控制台输出如下:

在这里插入图片描述

nextwork 加载的资源如下:

在这里插入图片描述

当点击按钮后,src_info_js.main.js 文件被加载

在这里插入图片描述

分析打包后的源码@H_301_88@

首先将源码折叠

(function (modules) {
  // xxxx
})({
  // xxx
})

这是一个自执行函数

函数参数@H_301_88@

在这里插入图片描述


webpack将所有的import moduleName from 'xxModule’都变成了一个Map对象,key为文件路径,value为一个可执行的函数,而函数内容其实就是模块中导出的内容,当然,模块自己也被webpack做了一些处理,接着往下进行。

从打包后Map对象中能找到我们代码中的各个模块,以及模块的内容,但是也多了很多不属于我们编写的代码,比如以__webpack_require__开头的代码,这些又是什么呢?其实是webpack自定义的一些方法。

.tsx webpack编译失败:意外的令牌<

.tsx webpack编译失败:意外的令牌<

我的应用程序使用.ts,.js和.jsx文件进行编译并运行。现在,我尝试将.jsx文件更改为.tsx,它会中断。

如何解决此编译错误:

ts-loader: Using typescript@1.6.2 and C:\users\ruser\Desktop\Downloads\divinote\site\tsconfig.json                                                                                                                                                    67% 226/234 build modulesModuleParseError: Module parse failed: C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\ts-loader\index.js?cacheDirectory!C:\users\ruser\Desktop\Downloads\divinote\site\src\app\views\header\DiviAppBar.tsx Line 15: Unexpected token <You may need an appropriate loader to handle this file type.|     }|     DiviAppBar.prototype.render = function () {|         return (<AppBar />);|     };|     return DiviAppBar;    at DependenciesBlock.<anonymous> (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack\lib\NormalModule.js:113:20)    at DependenciesBlock.onModuleBuild (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:310:10)    at nextLoader (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:275:25)    at C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:292:15    at context.callback (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:148:14)    at Object.loader (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\ts-loader\index.js:431:5)    at WEBPACK_CORE_LOADER_EXECUTION (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:155:71)    at runSyncOrAsync (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:155:93)    at nextLoader (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:290:3)    at C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\webpack-core\lib\NormalModuleMixin.js:259:5    at Storage.finished (C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\enhanced-resolve\lib\CachedInputFileSystem.js:38:16)    at C:\users\ruser\Desktop\Downloads\divinote\site\node_modules\graceful-fs\graceful-fs.js:76:16    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:404:3)                                                                                                                                                                                     69% 337/338 build moduleschild_process.js:484

当我编译这段代码时:

"use strict";import React = require(''react'');import AppBar = require(''material-ui/lib/app-bar'');class DiviAppBar extends React.Component{    render()    {        return (            <AppBar  />        );    }}export = DiviAppBar;

与此webpack配置文件:

''use strict'';var webpack = require(''webpack'');var HtmlWebpackPlugin = require(''html-webpack-plugin'');var CopyWebpackPlugin = require(''copy-webpack-plugin'');var path = require(''path'');var rootPath = __dirname; //sitevar srcPath = path.join(rootPath, ''src''); //site/srcmodule.exports ={    bail: true,    cache: true,    context: rootPath,    debug: true,    devtool: ''inline-source-map'', //''eval-cheap-module-source-map'',''inline-source-map''    target: ''web'',    devServer:    {        contentBase: ''./dist'',        historyApiFallback: true    },    entry:    {        app: path.join(srcPath, ''app/main.jsx''),        lib: [''react'', ''react-router'']    },    output:    {        path: path.join(rootPath, ''dist''),        publicPath: '''',        filename: ''[name].js'',        library: [''[name]'', ''[name]''],        pathInfo: true    },    resolve:    {        root: srcPath,        extensions: ['''', ''.js'', ''.jsx'', ''.ts'', ''.tsx''],        modulesDirectories: [''node_modules'', ''src'', ''typings'']    },    module:    {        loaders:        [            {test: /\.js$/, loader: ''babel-loader?cacheDirectory'', exclude: /(node_modules|bower_components)/ },            {test: /\.jsx$/, loader: ''babel-loader?cacheDirectory'', exclude: /(node_modules|bower_components)/ },            {test: /\.ts$/, loader: ''ts-loader?cacheDirectory'', exclude: /(node_modules|bower_components)/ },            {test: /\.tsx$/, loader: ''ts-loader?cacheDirectory'', exclude: /(node_modules|bower_components)/ },            {test: /\.scss$/, loaders: [''style'', ''css'', ''sass'']},            {test: /\.png$/, loader: ''file-loader''},            {test: /\.jpg$/, loader: ''file-loader''},            {test: /\.jpeg$/, loader: ''file-loader''},            {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: ''file-loader?mimetype=image/svg+xml''},            {test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff"},            {test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff"},            {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/octet-stream"},            {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader"},        ]    },    plugins:    [        new CopyWebpackPlugin        ([            { from: ''src/images'', to: ''images'' }        ]),        new webpack.optimize.CommonsChunkPlugin(''lib'', ''lib.js''),        new HtmlWebpackPlugin        ({            inject: true,            template: ''src/index.html''        }),        new webpack.NoErrorsPlugin()    ]};

和这个tsconfig.json文件:

{    "compilerOptions":    {        "jsx": "preserve",        "noImplicitAny": true,        "module": "commonjs",        "removeComments": false,        "sourceMap": true,        "target": "es5"    },    "files": [],    "exclude":    [        "node_modules",        "dist"    ]}

答案1

小编典典

第一个问题与 Martin 提到的“ jsx”配置有关。将“ jsx”设置为“反应”。

第二个问题与您的代码有关。像这样更改它:

class DiviAppBar extends React.Component<Props, State> ...

为道具创建一个界面,为状态创建另一个界面。如果没有,请使用空对象。

class DiviAppBar extends React.Component<{}, {}> ...

Dynamic imports with webpack

Dynamic imports with webpack

问题

使用 webpack 构建, 动态去加载 css 时,为什么使用 import() 会报错,使用 System.import() 可以?

$ webpack => 2.6.1

dynamic-load-css-file
dynamic-load-css-file-error


原因

require.ensure()

在 webpack1.x 中提供了 require.ensure() 方法动态导入文件,其函数签名如下:

require.ensure(dependencies, callback, chunkName)

简单示例:

require.ensure([], function(require) {
  const foo = require("./module");
});

注:require.ensure() 出自 CommonJS 中有一个 Modules/Async/A 规范,该规范定义了 require.ensure 语法。webpack 基于此基础,在打包的时候根据 require.ensure() 进行代码切分,并异步加载切分后的代码。

System.import()

ES6 Loader 规范定义了 System.import 方法,用于在运行时动态加载 ES6 模块,Webpack 把 System.import 作为拆分点;所以也可以通过 System.import() 方法实现动态引入,与 require.ensure()
不同的是 System.import() 返回的是一个 Promise,如:

System.import("./module")
  .then(module => console.log(module))
  .catch(err => console.log(Chunk loading failed))

import()

而在 webpack v2 (v2.1.0-beta.28) 废弃了 System.import() 方法,在 webpack v3 会完全删除System.import() 方法, 进而支持 ECMAScript State 3 草案阶段的原生 import() 方法来替代 System.import() 方法。

import("./module").then(module => {
    return module.default;
  }).catch(err => {
    console.log("Chunk loading failed");
  });

import

ES6 模块与 CommonJS 模块的差异 ,自行理解:

  • CommonJS

    • CommonJS 和 AMD 模块是运行时加载

    • CommonJS 模块就是对象,输入时必须查找对象属性

    • CommonJS 模块输出的是值的缓存,不存在动态更新

  • ES6 Module

    • ES6 模块是编译时加载

    • ES6 模块不是对象,而是通过 export 命令显式指定输出的代码,再通过 import 命令输入

    • ES6 export 语句输出的接口,与其对应的值是动态绑定关系

由于 ES6 中的模块是编译时加载,import 命令会被 JavaScript 引擎静态分析,先于模块内的其他模块执行。所以,下面的代码会报错:

// 报错
if (x === 2) {
  import MyModual from ''./myModual'';
}

注:在 Webpack 2(v2.2.0-rc.5) 中增加对 ES6 模块的原生支持。这意味着 Webpack 现在可以识别 import 和 export,不需要先把它们转换成 CommonJS 模块的格式。

require()、import、import()

require() 是 CommonJS 的实现,用于运行时加载,推荐阅读 require() 源码解读

import 是 ECMAScript 6 Module 的语法,import 是静态执行,推荐阅读 import 命令

import() 函数是 ECMAScript Stage 3 草案阶段的语法;用于完成动态加载即运行时加载,可以用在任何地方。import()函数 返回的是一个 Promise。类似于 CommonJs 的 require() ,区别主要是前者是异步加载,后者是同步加载,推荐阅读 proposal-dynamic-import

import() 的适用场景:

  • 按需加载

  • 条件加载

  • 动态的模块路径

结论

webpack 的 Dynamic Imports 实现主要是利用 ECMAScript的 import() 动态加载特性,而 import() 目前只是一个草案,如果需要用此方法,需要引入对应的转换器,如 babel-plugin-syntax-dynamic-import。

模块化的实现对比

CommonJS AMD CMD ES6 Module
解决的问题 模块化开发 模块化开发 模块化开发 模块化开发
适用环境 服务端 浏览器 浏览器 浏览器/服务端
加载方式 同步加载/异步加载 异步加载 异步加载 同步加载/异步加载
模块定义 module.exports define(id?,dependencies?,factory) define(function(require,exports,module){ }) export
模块加载 require()/require.ensure() require([module], callback) require(module) import / import()
执行时机 提前执行 延迟执行
依赖原则 依赖前置 依赖就近
规范化的实现 require.js SeaJS
webpack 的支持 require.ensure() require() import / import()

参考

  • ES proposal: import() – dynamically importing ES modules

  • code-splitting-with-es2015

推荐阅读

  • Webpack 2 有哪些新东西

  • ES6 的模块系统

  • Module 的加载实现

ES6通过babel转码使用webpack使用import关键字

ES6通过babel转码使用webpack使用import关键字

使用了babel转码,使用import和export的时候,在浏览器运行代码的时候,提示

babel只是个翻译,假设a.js 里 import 了 b.js

对a.js进行转码,只是翻译了a.js,并不会把b.js的内容给读取合并进来

如果想在最终的某一个js里,包含 a.js,b.js 的代码,那就需要用到打包工具

也就是webpack等工具了

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

npm+babel+webpack解决不能import问题

npm+babel+webpack解决不能import问题

引言

当自己从土里搭建起来一个网站,即使是最原始的那种网站,菜鸟如我也会遇到有许许多多琐碎又细小的问题。本篇幅记录关于代码转换和代码打包相关工作。

这两个问题主要的矛盾在于,之前我一直是用<script>来加载各类css,js,ico等文件的:
本地资源:

<link="icon" href="http://www.xxxxxxxxx.top/icon/icon.ico">
<link="stylesheet" href="http://www.xxxxxxxxx.top/css/globalStyle.css type="text/css">
<script src="http://www.xxxxxxxxx.top/node_modules/socket.io-client/dist/socket.io.js"></script>

各类cdn:

<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    
<script src="https://cdn.bootcss.com/react-router/5.0.1/react-router.min.js"></script>
<script src="https://cdn.bootcss.com/react-router-dom/5.0.1/react-router-dom.min.js"></script>
    
<script src="//cdn.jsdelivr.net/npm/leancloud-storage@3.15.0/dist/av-live-query-min.js"></script>

有一天,有一些cdn崩了,导致网站没法用。我就想npm install到本地吧,然后用import加载各类文件。然后就遇到了各类问题,虽然最后解决方法看起来很简单,但过程很艰辛、费时间,要是不写一篇文章总感觉时间花的太不值了。一方面给未来的自己查看起来方便,一方面希望能给有幸看到这篇文章的小伙伴们节约点时间。

babel

因为网站用的React搭建的,Reactjsx语法用起来很开心,但jsx需要翻译成js官方语法&浏览器认识的语法才能使用。React官网推荐使用Babeljsx进行翻译。所以,那就Babel咯~
react官网-babel-1.png

react官网-babel-2.png

babel是什么

babel是一个JavaScript 编译器,它将各类不同版本的javascript语言标准翻译成你想要的版本。意思就是,最新版本的javascript语法,部分版本的浏览器不支持,需要转换成低版本的javascript语法,才能实现兼容。引用Babel官网的话:

babel官网介绍.png

Babel有这么几个主要的概念:Presets、Plugins、Config Files、Cli

Babel:Plugins

Plugins,插件,是Babel实现功能的主要模块。通过安装不同的插件,Babel可以实现不同的功能。

例如:

  • @babel/plugin-transform-arrow-functions:这个插件将箭头函数:() => {}(ES6)转换成低版本的函数申明
  • @babel/plugin-transform-classes:这个插件将class申明:class Heng extends Ha(){}(ES6)转换为低版本的函数申明和原型链
  • @babel/plugin-transform-modules-commonjs:这个插件将import/export语法转换成commonjs标准的require/export
  • @babel/plugin-transform-react-jsx:这个插件将jsx语法转换成React.createElement()

Plugins的使用,你只需要通过npm install 插件名称安装一下,再通过配置文件+cli或者cli使用就ok了

Babel:Presets

Presets,预设,就是Babel将各类插件整合在一起,来提供一系列功能。

官方Presets:

  • @babel/preset-env:这个是最新Babel-7版本出的预设,抛弃老版本繁乱的插件,这个预设通过配置能根据浏览器版本,将代码自动翻译成最适合的版本。
  • @babel/preset-flow:这个我看不太懂
  • @babel/preset-react:这个是专为React做的预设,能很好的将React简便写法翻译成React正经语法
  • @babel/preset-typescript:这个是转为TypeScript做的预设,只包含一个插件

你也可以自己做一个Presets:

  • 把插件用数组组起来,文件取名myPreset.js

    module.exports = function() {
      return {
        plugins: [
          "pluginA",
          "pluginB",
          "pluginC",
        ]
      };
    }
  • 也可以引用其它Presets

    module.exports = () => ({
      presets: [
        require("@babel/preset-env"),
      ],
      plugins: [
        [require("@babel/plugin-proposal-class-properties"), { loose: true }],
         require("@babel/plugin-proposal-object-rest-spread"),
      ],
    });
  • 在配置Config Files中引用,npm模块名或者相对路径

    {
      "presets": ["babel-preset-myPreset"]
    }
    
    {
      "presets": ["./myProject/myPreset"]
    }

Presets的使用,你只需要通过npm install 预设名称安装一下,再通过配置文件+cli或者cli使用就ok了

Babel:Usage

有很多方式使用Babel,这里就只介绍两种,因为我就会这两种

Babel:Usage:Config Files+Cli

通过配置文件可以配置Babel用什么插件、用哪种预设、设置环境变量、忽略某一文件夹等。菜鸟如我简单用用就设定用什么插件用哪种环境变量就行了~

  • npm init的地方,手动新建文件babel.config.json or babel.config.js或者.babelrc.json。关于两种区别,Babel官网相关部分是这样描述的:
    babel官网configFiles.png
  • 配置文件内容:
    babel.config.json.babelrc.json

    {
      "presets": ["presetName1","presetName2"],
      "plugins": ["pluginName1","pluginName2"]
    }

    babel.config.js

    module.exports = function (api) {
     api.cache(true);
    
     const presets = [ ... ];
     const plugins = [ ... ];
    
     return {
       presets,
       plugins
     };
    }
  • 接下来是Cli部分,命令行中输入:

    npx babel -w 原始文件地址/原始文件名 --out-file 输出文件地址/输出文件名

    -w表示监听,--out-file表示后面跟的是输出文件信息。命令执行后,会自动调用配置文件中的相关配置。

Babel:Usage:Cli

纯命令行模式使用

  • 命令行中输入:

    npx babel script.js --out-dir lib --watch --out-file script-compiled.js --source-maps --ignore "src/**/*.spec.js","src/**/*.test.js" --presets=@babel/preset-env,@babel/flow --plugins=@babel/proposal-class-properties,@babel/transform-modules-amd

其实就是将配置文件中的配置全移到命令行内实现,利用--watch、--presets、--plugins、--ignore、--source-maps等这样的命令行参数。参数具体含义可参考Babel官网相关内容。

webpack

为什么会用到webpack呢?是这样的。当我使用import加载模块名的时候,浏览器会报错

加载模块名:

import {HashRouter,Switch,Link,NavLink,Route,BrowserRouter} from "react-router-dom";

报错:
Uncaught TypeError: Failed to resolve module specifier "react-router-dom". Relative references must start with either "/", "./", or "../"

当我使用import加载路径/文件名的时候,浏览器会报错

加载路径/文件名:

import React from "./node_module/react/index.js";

报错:
Uncaught TypeError: Failed to resolve module specifier: "react"
export ''default'' was not found in "./node_module/react/index.js"

嘛~具体的报错内容不记得了,反正就是这个意思,浏览器总是会报错。如果使用Babel的智能翻译预设@babel/preset-env进行翻译后,Babel会将import都翻译成require,这样导致的结果还是浏览器报错:

翻译前:

import React from "react";

翻译后:

var React = require("react");

报错:
ReferenceError: require is not defined

经过费时的寻找解决方案,我只能通过打包工具对importrequire进行处理。webpack那么火,那就用webpack吧~

webpack是什么

webpack就是JavaScript静态模块打包器(static module bundler)。它可以将各类资源import到一起,包括.css、.png、.xml、.js等文件,然后“打包”生成一个新的js文件。新文件仅包含依赖的文件,并且可文件压缩,还能代码压缩。

webpack有这么几个主要的概念:Entry、Output、Loaders、Plugins、Mode

Webpack: Usage

webpack的使用很简单。首先,创建一个配置文件webpack.config.js,然后,执行打包命令npx webpack。这样就会在你指定的目录下生成新的js文件,在你的html内引用这个js文件就ok了~

  • 安装

    npm install webpack webpack-cli --save-dev
  • 创建配置文件

    const path = require(''path'');
    
    module.exports = {
        entry: 入口文件,
        output: {
            path: 出口文件目录,
            filename: 出口文件名
        },
        module: {
            rules: [
                各类loader配置项
            ]
        },
        plugins: [各类插件名],
    };
  • 使用

    npx webpack

Webpack:Entry

Entry用于在配置文件中配置打包入口。意思就是从Entry开始,查找所有它的依赖,进行打包。常用格式如下:

module.exports = {
  entry: ''./path/to/my/entry/file.js''
};

Webpack:Output

Output用于在配置文件中配置打包后新文件的位置。常用格式如下:

const path = require(''path'');

module.exports = {
  entry: ''./path/to/my/entry/file.js'',
  output: {
    path: path.resolve(__dirname, ''dist''),
    filename: ''my-first-webpack.bundle.js''
  }
};

path表示输出文件的绝对路径__dirname表示该配置文件所在的绝对路径,filename表示输出的新文件名,path.resolve()会将括号内的参数解析成一个完整的路径、当然用之前需要引入nodejs模块:const path = require(''path'');。如上述例子会打包输出到__dirname/dist/my-first-webpack.bundle.js

Webpack:Loaders

Loaders用以使webpack能够加载打包非js文件。所有的Loaders可以查看官网。常用格式如下:

const path = require(''path'');

module.exports = {
    entry: ''./path/to/my/entry/file.js'',
    output: {
        path: path.resolve(__dirname, ''dist''),
        filename: ''my-first-webpack.bundle.js''
    },
    module: {
        rules: [
            {
                test: 文件名正则,
                use: [
                    "loader-name"
                ]
            }
        ]
    }
};

Webpack:Loaders:css

  • 安装

    npm install --save-dev style-loader css-loader
  • 修改配置文件

    module: {
     rules: [
       {
         test: /\.css$/,
         use: [
           ''style-loader'',
           ''css-loader''
         ]
       }
     ]
    }
  • 使用

     import ''./style.css'';

Webpack:Loaders:file

file-loader可用来加载图片或者文字或者其它文件类型。

  • 安装

    npm install --save-dev file-loader
  • 修改配置文件

    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            ''style-loader'',
            ''css-loader''
          ]
        },
       {
         test: /\.(png|svg|jpg|gif)$/,
         use: [
           ''file-loader''
         ]
       },
       {
         test: /\.(woff|woff2|eot|ttf|otf)$/,
         use: [
           ''file-loader''
         ]
       }
      ]
    }
  • 使用
    入口文件:

     import ''./style.css'';

    style.css:

    @font-face {
        font-family: ''MyFont'';
        src:  url(''./my-font.woff2'') format(''woff2''),
              url(''./my-font.woff'') format(''woff'');
    }
    
    .hello {
        font-family: ''MyFont'';
        background: url(''./icon.png'');
    }

Webpack:Plugins

Plugins,插件,用于帮助webpack实现各种各样的功能。如下例子clean-webpack-plugin插件帮助清理文件夹,删除不需要的依赖文件。

  • 安装

    npm install clean-webpack-plugin --save-dev
  • 修改配置文件

      const path = require(''path'');
      const CleanWebpackPlugin = require(''clean-webpack-plugin'');
    
      module.exports = {
        entry: ''./path/to/my/entry/file.js'',
        plugins: [
          new CleanWebpackPlugin([''dist'']),
        ],
        output: {
          path: path.resolve(__dirname, ''dist''),
          filename: ''[name].bundle.js'',
        }
      };
  • 进行打包命令

Webpack:Mode

mode用来在配置文件中指定环境:development&productionwebpack在不同环境下会加载不同的插件和处理方式。

  • 修改配置文件

    module.exports = {
       mode: "production",
    }
    module.exports = {
      mode: "development",
    }

总结

我的目标是将<script>标签尽可能多的转换成代码内import。一方面减少加载各类<script>资源的时间,import资源都安装在服务器上,就只需要加载一个文件就ok了;一方面减少cdn不确定的因素。

曾经的资源加载方式:

<script src="https://cdn.bootcss.com/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.8.6/umd/react-dom.production.min.js"></script> -->
<script src="https://cdn.bootcss.com/react-router/5.0.1/react-router.min.js"></script>
<script src="https://cdn.bootcss.com/react-router-dom/5.0.1/react-router-dom.min.js"></script>
<script src="http://www.dogcatpig.top/js_rely/babel_min_6.26.0.js"></script>

上面babel不需要import,安装预设@babel/preset-react、新建配置文件babel.config.json后、用命令npx babel -w 原始文件地址/原始文件名 --out-file 输出文件地址/输出文件名输出翻译后文件。

但是,其它的资源虽然import/export已经是javascript语言标准了,但用起来还是不行。所以需要webpackwebpack不仅能处理import/export & require/export,还能将各种资源打包到一个js文件中,极大的减少网站加载时间。亲测如果没缓存,至少减少一半时间,有缓存2毫秒左右。用法也很简单,安装你想要的loaders & plugins,新建配置文件webpack.config.js,用命令npx webpack输出。

总结流程.png

文中配置文件均放置在package.json同目录

关于import被webpack编译成了啥?import webpack的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于.tsx webpack编译失败:意外的令牌<、Dynamic imports with webpack、ES6通过babel转码使用webpack使用import关键字、npm+babel+webpack解决不能import问题的相关知识,请在本站寻找。

本文标签: