GOPack is a pre written javascript bundler, which was created using webpack. It configures your project to use the already existing webpack loaders and plugins to generate static files.
Inorder to install this package you need to have Node Js running on your system. If you don't have Node Js you can install it from their website https://nodejs.org. If you have Node Js installed, navigate to your project root folder and run npm i @go-pack/gopack
in your terminal.
To initialize the project (Set up the project files), run npx gopack init
. This command will create the files you need for webpack to work, and install the devDependencies
into your node_modules
folder.
The files that will be created are:
- package.json (This will merge existing package.json contents into a new package.json file)
- webpack.config.js
- .browserslistrc
- postcss.config.js
- gopack.config.js
When you run npx gopack init
, it will initialize your project and create some files, but if it files any existing file it will ask for permission to overwrite it. It will also ask for permission to run npm install -f
in your project. To skip the permissions you can run npx gopack init -y
Inorder to start the development server, you can run npx gopack start
, the equivalent of this is npx webpack
+ npx webpack serve
. Your server will run on http://localhost:8080
by default. Make sure you have the gopack.config.js
file in your project's root folder and export an object as default, unless this will throw an error.
Inorder to start the production server, you can run npx gopack serve
, the equivalent of this is npx cross-env MODE=production webpack
+ npx cross-env MODE=production webpack serve
. Your server will run on http://localhost:8080
by default. Make sure you have the gopack.config.js
file in your project's root folder and export an object as default, unless this will throw an error.
Inorder to bundle your project into static files, you can run npx gopack build
, the equivalent of this is npx cross-env MODE=production webpack
. Doing this will bundle your project without starting the production server. Make sure you have the gopack.config.js
file in your project's root folder and export an object as default, unless this will throw an error.
The gopack.config.js
file is written to help developers who are not familiar with webpack to customize the build output to their taste.
It comprises of key value pairs that enables flexibility in one's project. Which are:
- generateCSSFiles
- devtool
- useCoreJs
- entry
- outputFilenameFormat
- outputImageNameFormat
- outputFilename
- outputFolder
- pages
- assetsFolder
- mapPlugins
- libraries
- node
- target
- copy
This accepts a boolean true
or false
. It indicates if webpack should inject CSS styles into the style tags <style></style>
of every HTML page or if it should generate CSS files and them to various HTML pages.
This accepts the same parameters the webpack devtool does. It must be the same parameter that would be inserted into the webpack devtool
key, unless webpack will throw an error upon build.
The most common used options are either false
which is a boolean
or source-map
which is a string
. If the source-map
is inserted, it generates javascript and CSS map files which will be used to trace code using the browser's devtool
. The source-map
option is best used for development
mode, while the false
option is best used for production
mode.
This accepts a boolean. It signifies if babel.config.js
should generate code to support older browser versions when bundling using the core-js
npm package. It is false
by default.
NB: This feature generates a lot of code for backwards compatibility, which will end up making your bundled javascript code large. use at your own risk
This accepts either a string
or an object
. It is indicates where webpack should start building our files from. The default value is ./src/index.js
. To specify multiple entrypoint, you create an object with key value pairs. the key being the chunk
and the value being the path to the file. E.g.
entry: {
chunk: "path/to/file.js";
}
This is the format in which webpack should name our bundled files - chunks
. It is used if the entry
parameter is an object
. It accepts a string. It is written in this format [name].bundle.js
. The [name]
block is a variable which signifies the name each generated file chunk
. The bundle
extension is optional, but the js
extension is compulsory. Therefore, if you specify the entry file as:
entry: {
index: "./src/index.js";
}
The output will be index.bundle.js
This is the format in which webpack should name our bundled assets/images. It accepts a string. It is written in this format [name][hash][ext][query]
. The [name]
block is a variable which signifies the name each generated file/image. The [hash]
block is the unique hash webpack generates for each file. The [ext]
block is the file extension. The [query]
block is optional. Therefore, if you specify the entry file as:
entry: {
index: "./src/index.js";
}
The output will be index.bundle.js
This is the name you want to give your bundled javascript file. This is used if the entry
parameter is a string
or not specified. This key accepts a string
, which must end with the .js
extension. E.g. index.js
This specifies the folder where all the webpack generated files should be located. It accepts a string
. E.g. public
This is used if you have any HTML file/files which you want to be bundled. It accepts an array
of objects
. E.g.
public: [
{
template: path.resolve(__dirname, "src/index.html"),
filename: "index.html",
},
];
The template key signifies the path to the HTML document, the filename signifies the name it should give the generated HTML document during build.
Each object also accepts a parameter called chunk
, which is an array of generated JavaScript/CSS file links to be inserted into the HTML document. The items passed as values to the chunk
array must be same as the keys passed into the entry
object. E.g
entry: {
index: './src/index.js',
about: './src/about.js',
contact: './src/contact.js',
},
public: [
{
template: path.resolve(__dirname, "src/about.html"),
chunk:["index","about"],
filename: "about.html",
}
]
The chunks
specifies which bundled javascript files should be included in the HTML page. I.e
gopack.config.js
entry: {
index: './src/index.js',
about: './src/about.js',
contact: './src/contact.js',
},
public: [
{
template: path.resolve(__dirname, "src/index.html"),
chunk:["index"],
filename: "index.html",
}
]
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Index</title>
<!-- Automatic import -->
<script defer src="index.js"></script>
</head>
</html>
This accepts a string which is the name or path to the folder the bundled images and assets will be stored. E.g. images
or path/to/images
.
This accepts an object
. The value of this is passed to the webpack.ProvidePlugin()
class. This automatically load modules instead of having to import or require them everywhere in your project.
Here is an example of it's possible values:
{
identifier: "module";
// OR
identifier: path.resolve(path.join(__dirname, "path/to/module.js"));
}
The identifier is a user-defined value/key, while the module is either the name of a library in the node_modules
folder or path to a javascript/typescript file. The module is automatically loaded and the identifier is filled with the exports of the loaded module (or property in order to support named exports).
Common usages of this option are:
To automatically load jQuery we can point both variables it exposes to the corresponding node module:
{
$: 'jquery',
jQuery: 'jquery',
}
Then in any of our source code:
// in a module
$("#item"); // <= works
jQuery("#item"); // <= also works
// $ is automatically set to the exports of module "jquery"
This accepts an array
of string
or objects
. It specifies which libraries webpack should support when bundling your project. If you are adding an object to the list, you should do so in this format.
{
name: "name-of-library",
...//other properties specified
}
Here are it's possible values to be inserted into the list:
- react
- vue
- angular OR
{name: "angular", src: "path/to/your/source/folder"}
- typescript
- pug
- hbs
Examples are:
- Let's say you want to support React Js, you specify
{
...,
libraries: ["react"]
}
- If you want to support multiple libraries e.g. Typescript, Angular you specify:
{
...,
libraries: ["typescript", {name: "angular", src: "path/to/your/source/folder"}]
}
N.B: The values are case-sensitive so make sure you use exactly what's specified in the list of possible values
This is passed into the webpackConfig.node
object. It accepts an object
as a value. It specifies certain Node Js globals to polyfill. It should be used if you are running on a Node Js environment. To learn more visit https://webpack.js.org/configuration/node/.
This tells webpack the environment it should target when building your project. It defaults to browserslist
. It should be set to node
to support a Node Js environment, it should be set to web
or browserslist
to support a web environment. To learn more visit https://webpack.js.org/configuration/target/
This specifies individual files or entire directories which already exist, that webpack should copy to the build directory. It's value is being passed to the new CopyWebpackPlugin()
class.
It accepts an object
of keys. I.e
- patterns (Array)
- options (Object)
The patterns
property accepts a list of objects
which properties are:
[from
, to
, context
, globOptions
, filter
, toType
, force
, priority
, transform
, transformAll
, noErrorOnMissing
, info
]. We will only explain the from
and to
properties, to learn more visit https://webpack.js.org/plugins/copy-webpack-plugin.
- from:
This is an object that accepts a
string
, i.e. The path to the file/folder to be copied. - to:
This is an object that accepts a
string
, i.e. The destination of the copied file or folder.
E.g
{
copy: {
patterns: [
{
from: "path/to/file.js",
to: "path/to/destination/file.js",
},
{
from: "path/to/folder",
to: "path/to/destination/folder",
},
{
from: path.resolve(__dirname, "folder").replace(/\\/g, "/"),
to: path.resolve(__dirname, "folder").replace(/\\/g, "/"),
},
];
}
}
N.B: Don't use directly
\\
infrom
orto
option if it is a glob (i.epath\to\file.ext
) option because on UNIX the backslash is a valid character inside a path component, i.e., it's not a separator. On Windows, the forward slash and the backward slash are both separators. Instead please use/
.
To learn more please visit https://webpack.js.org/plugins/copy-webpack-plugin.
GOPack also supports the use of other libraries which are:
GOPack has built-in support for react. It uses the @babel/preset-react
library to transpile JSX to javascript. If you need to use React Js in your project you just have to install both the react
and react-dom
libraries. Then create a root node in your HTML file where react
will inject the transpiled JSX code. To learn more about React Js, visit https://legacy.reactjs.org/docs/getting-started.html.
GOPack has built-in support for vue. It uses vue-loader
, VueLoaderPlugin
, vue-style-loader
, vue-template-compiler
to handle .vue
files. If you need to use Vue Js in your project you just have to install the vue
library. Then create one or multiple root nodes in your HTML file where vue
will inject the transpiled Vue Js code. To learn more about Vue Js, visit https://vuejs.org/guide/introduction.html.
N.B: To make use of Vue Js, make sure you have at least 1 .vue
file in your project folder, unless webpack will throw an error
GOPack has built-in support for angular. It doesn't use any extra loader to handle angular projects. But, it does add one plugin to the webpack plugins
array which is the new webpack.ContextReplacementPlugin()
, in order to support angular core and skip all system imports angular does by itself. It also adds one property to the webpack devServer
object which is the historyApiFalback
and sets it to true
, in order to support angular js routing.
If you need to use Angular Js in your project you just have to install the necessary angular libraries, and add angular
to the list of libraries you want to support in gopackConfig.libraries
array. I.e.
{
...,
libraries: ["angular"]
}
You can also add an object
if you want to specify the link to your project's source folder. I.e
{
...,
libraries: [{
name: "angular",
src:"path/to/your/project's/source/folder"
}]
}
The src
value is optional, but if provided it will be added to the new webpack.ContextReplacementPlugin()
plugin as the path to the project's source folder, else the value ./src
will be used instead.
For more detailed information on how to use Angular Js, visit https://docs.angularjs.org/guide.
GOPack has built-in support for typescript. It uses the ts-loader
loader to handle both .ts
and .tsx
files. If you need to use Typescript in your project you just need to install the typescript
library and create a tsconfig.json
file in your project's root folder. To learn more about Typescript, visit https://www.typescriptlang.org/docs/handbook/typescript-from-scratch.html.
GOPack has built-in support for jQuery. If you need to use jQuery in your project you just need to install the jQuery
library in your project. To learn more about jQuery, visit https://api.jquery.com/.
GOPack has built-in support for SASS. It uses the sass-loader
loader to handle both .sass
and .scss
files. If you need to use SASS in your project you just need to install the sass
library in your project. To learn more about SASS, visit https://sass-lang.com/documentation/.
GOPack has built-in support for ejs. It uses the HTMLWebpackPlugin
library to handle .ejs
files. There is one problem with using .ejs
files, the html-loader
doesn't parse images/files imported in .ejs
files. Therefore, to use import images you have to do it this way.
// WRONG
<img src="./images/picture.jpg" />
// CORRECT <img src="<%= require("./images/picture.jpg") %>" />
You can also add dynamic variables using the <%= htmlWebpackPlugin.options.variable_name %>
syntax. Then specify variable_name
in the object passed into the pages
array in gopack.config.js
. E.g.
In the index.ejs file
<head>
<title><%= htmlWebpackPlugin.options.variable_name %></title>
</head>
Then in the gopack.config.js
{
...,
pages: [
{
template: path.resolve(__dirname, "src/index.ejs"),
filename: "index.html",
variable_name: "Index page"
}
]
}
To learn more about ejs, visit https://ejs.co/#docs.
GOPack has built-in support for pug. It uses the pug-loader
library to handle .pug
files. There is one problem with using .pug
files, just like .ejs
files the html-loader
doesn't parse images/files imported in .pug
files. Therefore, to use import images you have to do it this way.
// WRONG
img((src = "./images/picture.jpg"));
// CORRECT
img((src = require("./images/picture.jpg")));
You can also add dynamic variables by just assigning htmlWebpackPlugin.options.variable_name to an element. Then specify variable_name
in the object passed into the pages
array in gopack.config.js
. E.g.
In the index.pug file
head;
title = htmlWebpackPlugin.options.variable_name;
Then in the gopack.config.js
{
...,
pages: [
{
template: path.resolve(__dirname, "src/index.pug"),
filename: "index.html",
variable_name: "Index page"
}
]
}
To learn more about pug, visit https://pugjs.org/api/getting-started.html.
GOPack has built-in support for handlebars. It uses the handlebars-loader
library to handle .hbs
files. There is one problem with using .hbs
files, just like the other non-html files, the html-loader
doesn't parse images/files imported in .hbs
files. But, you don't need to do any extra configuration because GOPack has added the object below in the rules
array for .hbs
files.
{
test: /\.hbs$/,
use: [
{
loader: "handlebars-loader",
// CODE RESPONSIBILE FOR PARSING LINKS TO IMAGES
query: {
inlineRequires: `/${gopackConfig?.assetsFolder || "images"}/`,
},
},
],
}
You can also add dynamic variables using the {{ htmlWebpackPlugin.options.variable_name }}
syntax. Then specify variable_name
in the object passed into the pages
array in gopack.config.js
. E.g.
In the index.hbs file
<head>
<title>{{ htmlWebpackPlugin.options.variable_name }}</title>
</head>
Then in the gopack.config.js
{
...,
pages: [
{
template: path.resolve(__dirname, "src/index.hbs"),
filename: "index.html",
variable_name: "Index page"
}
]
}
To learn more about handlebars, visit https://handlebarsjs.com/guide/.
In order to support a Node js environment, you need to set the target
option in the gopackConfig to node
. It defaults to browserslist
. You can add some key value pairs to the node
option in the gopackConfig file to configure Node Js polyfill. To learn more about the target
and node
options visit https://webpack.js.org/configuration/target/ and https://webpack.js.org/configuration/node/ respectively.
If you need to add any configuration to webpack which is not present in the gopack.config.js
, add it to the module.exports
object in the webpack.config.js
or better still to the variable belonging to that configuration. E.g.
//OUTPUT
const output = {
filename: gopackConfig?.entry
? gopackConfig?.outputFilenameFormat || "[name].bundle.js"
: gopackConfig?.outputFilename || "bundle.js",
path: path.resolve(gopackConfig?.outputFolder || "public"),
assetModuleFilename: `${
gopackConfig?.assetsFolder || "images"
}/[hash][ext][query]`,
clean: true,
};
The output
constant belongs to the output
key in the webpack configuration
module.exports = {
...,
output: output,
...
};