掌握JS模块化开发,编写高可用代码

开发一个模块管理引擎:css

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>

    <script>
        //AMD require.js
        // CMD sea.js
        //COMMONJS Node.js
        //UMD

        let module = (function () {
            const moduleList = {};

            function define(name, modules, action) {
                modules.map((m, i) => {
                    modules[i] = moduleList[m]; //获取到依赖的方法
                });

                moduleList[name] = action.apply(null, modules);
                // console.log(moduleList);
            }

            return { define };

        })();

        module.define('arr', [], function () {
            console.log('define');
            return {
                first(arr) {
                    return arr[0];
                },
                max(arr, key) {
                    return arr.sort((a, b) => b[key] - a[key])[0];
                }
            }
        });

        module.define('lesson', ['arr'], function (arr) {
            let data = [
                { name: 'html', price: 199 },
                { name: 'css', price: 265 },
            ];
            // console.log(arr);
            console.log(arr.max(data, 'price'));
        });

        module.define('a', [], function () {
            return {
                name: 'cyy',
                age: 18
            }
        });

        module.define('b', ['a'], function (a) {
            a.name = 'cyy2';
        });

        module.define('c', ['a'], function (a) {
            console.log(a);
        });



    </script>

</body>

</html>

 

模块的基本使用:html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>

    <script type="module">
        //引入时当前路径的./不可省略
        import { name, age, show } from './script.js';
        console.log(name, age);
        show();


    </script>

</body>

</html>

script.jsnode

let name = 'cyy';
let age = 18;
function show() {
    console.log('show');
}
export { name, age, show };

 

模块延迟解析与严格模式:webpack

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>
    <!-- 模块会在最后执行,此时元素已经渲染完毕 -->
    <!-- 使用type="module"时,默认是严格模式 -->
    <script type="module">
        let div0 = document.querySelector('div');
        console.log(div0);
    </script>


    <!-- 普通js必须在元素渲染以后使用 -->
    <script>
        let div = document.querySelector('div');
        console.log(div);
    </script>

    <div>cyy</div>

    <script>
        let div2 = document.querySelector('div');
        console.log(div2);
    </script>

</body>

</html>

 

做用域在模块中的体现:web

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>
    <!-- 普通脚本在全局顶级做用域里 -->
    <script>
        let url = 'www.baicu.com';
        console.log(url);
    </script>

    <!-- module在本身的块级做用域里
能够访问顶级做用域的内容
可是顶级做用域里的内容不能访问到module里面的 -->

    <!-- 想要使用module里的内容,必需要经过导入和导出 -->
    <script type="module">
        // console.log(url);

        let cyy = 'cyy';
        export { cyy };
    </script>

    <script>
        console.log(url);
    </script>

</body>

</html>

 

预解析的必要性:npm

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>
    <!-- 屡次重复导入时会报错 -->
    <script type="module">
        import { name, age } from './script.js';
        import { name, age } from './script.js';
        import { name, age } from './script.js';
        console.log(name);
    </script>

</body>

</html>

 

模块的具名导出与导入:json

// export let name = 'cyy';
// export function show() { console.log('show') }
// export class User {
//     static func() {
//         console.log('User-static-func');
//     }
// }
// 具名导出


// 批量导出
let name = 'cyy';
function show() { console.log('show') }
class User {
    static func() {
        console.log('User-static-func');
    }
}
export { name, show, User };

 

批量导入与建议:api

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>
    <!-- 具名导入 -->
    <script type="module">
        // 批量导入并设置别名
        import * as api from './script.js';

        console.log(api.name);
        api.show();
        api.User.func();
    </script>

</body>

</html>

 

别名使用:app

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>
    <!-- 具名导入 -->
    <script type="module">

        // 给导入的模块设置别名
        import { name as n, s } from './script.js';
        let name = 'cyy2';
        console.log(n);
        console.log(name);

        s();
    </script>

</body>

</html>

script.jsless

// 批量导出
let name = 'cyy';
function show() { console.log('show') }
class User {
    static func() {
        console.log('User-static-func');
    }
}
// 导出也能够设置别名
export { name, show as s, User };

 

default默认导出:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>
    <!-- 具名导入 -->
    <script type="module">

        // 默认导出的模块,导入时随便起什么名字均可以
        // import myModule from './script.js';
        // myModule.func();


        import myModule from './script.js';
        myModule.func();
    </script>

</body>

</html>

script.js

// 当模块只有一个功能时,能够设置默认导出

// 默认导出1
// export default class User {
//     static func() {
//         console.log('User-static-func');
//     }
// }


// 默认导出2
class User {
    static func() {
        console.log('User-static-func');
    }
}
export { User as default };

 

混合导入导出的使用:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>
    <!-- 具名导入 -->
    <script type="module">

        // 具名导出的须要花括号,默认导出的不须要花括号
        // import myModule, { show } from './script.js';
        // myModule.func();
        // show();


        import * as api from './script.js';
        console.log(api);
    </script>

</body>

</html>

script.js

// export default class User {
//     static func() {
//         console.log('User-static-func');
//     }
// }
// export function show() {
//     console.log('show');
// }


class User {
    static func() {
        console.log('User-static-func');
    }
}
function show() {
    console.log('show');
}
export { User as default, show };

 

默认导出模块的使用规范:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>
    <!-- 具名导入 -->
    <script type="module">

        // 默认导出的模块建议跟文件名同名,这样比较规范
        import script from './script.js';
        script.func();

    </script>

</body>

</html>

 

模块的合并导出:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>
    <script type="module">
        import * as api from './index.js';
        console.log(api);
    </script>

</body>

</html>

index.js

import * as script from './script.js';
import * as script2 from './script2.js';

export { script, script2 };

script.js

export default class User {
    static func() {
        console.log('User-static-func');
    }
}

script2.js

let name = 'cyy';
function show() {
    console.log('show');

}
export { name, show };

 

按需动态加载模块:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <style>
    </style>
</head>

<body>
    <button>click me</button>

    <script type="module">
        // document.querySelector('button').addEventListener('click', function () {
        //     //点击按钮以后按需加载模块
        //     import('./script.js').then(module => {
        //         console.log(module);
        //     })
        // });


        document.querySelector('button').addEventListener('click', function () {
            //点击按钮以后按需加载模块
            import('./script2.js').then(({ name, show }) => {
                console.log(name);
                show();
            })
        });
    </script>

</body>

</html>

script2.js

let name = 'cyy';
function show() {
    console.log('show');

}
export { name, show };

 

WEBPACK构建项目的软件安装:

webpack打包工具,安装以前先安装node.js

使用一下命令生成配置文件package.json

npm init -y

 

安装webpack工具包,若是安装慢能够使用淘宝 cnpm (opens new window)命令

cnpm i webpack webpack-cli --save-dev

 

修改package.json添加打包命令,实时查看更新后的效果

...
"main": "index.js",
"scripts": {
    "dev": "webpack --mode development --watch"
},
...

 

目录结构

index.html
--dist #压缩打包后的文件
--src
----index.js  #入口
----style.js //模块

 

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>Document</title>
  </head>
  <body>
    <script src="dist/main.js"></script>
  </body>
</html>

 

index.js内容以下

import style from "./style";
new style().init();

 

style.js

export default class Style {
    constructor() {

    }
    init() {
        document.body.style.backgroundColor = 'pink';
    }
}

 

执行打包

运行如下命令将生成打包文件到 dist目录,由于在命令中添加了 --watch参数,因此源文件编辑后自动生成打包文件。

npm run dev

 

能够看到html页面背景已经变成了粉色~

相关文章
相关标签/搜索