Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --webextension option to command line #2

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4f3beb2
Add --webextension option to command line
Andras-Simon Oct 19, 2019
43c7e4c
Add webextension-polyfill to package.json
Andras-Simon Oct 21, 2019
069d6a0
Modify webpack.common conifg to automatically include browser-polyfil…
Andras-Simon Oct 21, 2019
16fe0cf
Modify generated Manifest file to include browser-polyfill.js
Andras-Simon Oct 21, 2019
c212731
Modify --webextension option to --no-cross-browser
Andras-Simon Oct 23, 2019
157171c
Modiy static html pages to include browser-polyfill.js
Andras-Simon Oct 23, 2019
f6e1c7f
Modify manifest background scripts section to include browser-polyfil…
Andras-Simon Oct 23, 2019
c574e5d
Update index.js to generate projects according to the --no-cross-brow…
Andras-Simon Oct 28, 2019
111ac05
Update config/webpack.common.js to generate new projects according to…
Andras-Simon Oct 28, 2019
c68d3e1
Insert <%= polyfill => variable to the html templates
Andras-Simon Oct 28, 2019
5466a7b
Update README.md: add `--no-cross-browser` option
Andras-Simon Oct 28, 2019
1afe5fa
Update index.js
Andras-Simon Oct 29, 2019
87ca968
Create .nocrossbrowser.js template files for the popup template, also…
Andras-Simon Oct 29, 2019
04155cd
Update index.js
Andras-Simon Oct 29, 2019
a7ec375
Create .nocrossbrowser files for the devtools template, update origin…
Andras-Simon Oct 29, 2019
d113178
Create .nocrossbrowser files for override-page tamplate
Andras-Simon Oct 29, 2019
8298748
Update index.js: remove unneeded console.log statement
Andras-Simon Nov 2, 2019
43b9fd3
Using minfied version of webpack-polyfill
Andras-Simon Nov 2, 2019
ee72d1c
Replace <%= polyfill %> with <%= browser-polyfill %> in every file
Andras-Simon Nov 2, 2019
a1d53f9
Removed optional type attribute in script tag
Andras-Simon Nov 2, 2019
1c358a6
Checking indexOf return value for -1
Andras-Simon Nov 2, 2019
9e06e92
Update index.js: usign RegExp.test() instead of String.match()
Andras-Simon Nov 2, 2019
3203437
Update index.js: fixing webpack.config.js regex
Andras-Simon Nov 4, 2019
09241a5
Update index.js: using RegEx to determine if filename ends with '.noc…
Andras-Simon Nov 4, 2019
eac1322
Updated referenced resources to MDN articles
Andras-Simon Nov 4, 2019
2dac67d
Update panel.js: fixing browser.devtools.inspectedWindow.eval returne…
Andras-Simon Nov 4, 2019
ce0e351
Update index.js
Andras-Simon Nov 4, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ chrome-extension-cli my-extension --override-page=history // Override Histo

Creates a Panel inside developer tools.

#### `chrome-extension-cli my-extension --no-cross-browser`

The generated project will not be cross-browser compatible by default.

## Contributing

See the [contribution guide](CONTRIBUTING.md) and join the contributors!
Expand Down
134 changes: 80 additions & 54 deletions config/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,60 +6,86 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const PATHS = require('./paths');

// To re-use webpack configuration across templates,
// CLI maintains a common webpack configuration file - `webpack.common.js`.
// Whenever user creates an extension, CLI adds `webpack.common.js` file
// in template's `config` folder
const common = {
output: {
// the build folder to output bundles and assets in.
path: PATHS.build,
// the filename template for entry chunks
filename: '[name].js',
},
devtool: 'source-map',
stats: {
all: false,
errors: true,
builtAt: true,
},
module: {
rules: [
// Help webpack in understanding CSS files imported in .js files
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
// Check for images imported in .js files and
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'images',
name: '[name].[ext]',
module.exports = env => {
// To re-use webpack configuration across templates,
// CLI maintains a common webpack configuration file - `webpack.common.js`.
// Whenever user creates an extension, CLI adds `webpack.common.js` file
// in template's `config` folder
const crossBrowser = (env.CROSS_BROWSER === 'true');
const common = {
output: {
// the build folder to output bundles and assets in.
path: PATHS.build,
// the filename template for entry chunks
filename: '[name].js',
},
devtool: 'source-map',
stats: {
all: false,
errors: true,
builtAt: true,
},
module: {
rules: [
// Help webpack in understanding CSS files imported in .js files
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
// Check for images imported in .js files and
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'images',
name: '[name].[ext]',
},
},
},
],
},
],
},
],
},
plugins: [
// Print file sizes
new SizePlugin(),
// Copy static assets from `public` folder to `build` folder, except .html files
new CopyWebpackPlugin([
{
from: '**/*',
context: 'public',
ignore: ['*.html']
},
]),
// copy static .html files from `public` folder to `build` folder, and replace the `<%= browser-polyfill %>` variable depending on config
new CopyWebpackPlugin([
{
from: '**/*.html',
context: 'public',
transform: (content) => {
const polyfill = '<script src="browser-polyfill.min.js"></script>';
if(crossBrowser) {
return content.toString().replace('<%= browser-polyfill %>', polyfill);
}
return content.toString().replace('<%= browser-polyfill %>', '');
}
},
]),
// Extract CSS into separate files
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
},
plugins: [
// Print file sizes
new SizePlugin(),
// Copy static assets from `public` folder to `build` folder
new CopyWebpackPlugin([
{
from: '**/*',
context: 'public',
},
]),
// Extract CSS into separate files
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
};
};

module.exports = common;
if(crossBrowser) {
// Copy browser-polyfill.js for cross browser compability
common.plugins.unshift(new CopyWebpackPlugin([
{
from: 'node_modules/webextension-polyfill/dist/browser-polyfill.min.js'
}
]));
}
return common;
}
50 changes: 45 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const packageFile = require('./package.json');
const { checkAppName, prettifyAppName } = require('./utils/name');
const generateReadme = require('./scripts/readme');
const tryGitInit = require('./scripts/git-init');
const browserPolyfillFilename = 'browser-polyfill.min.js';

let projectName;
const OVERRIDE_PAGES = ['newtab', 'bookmarks', 'history'];
Expand All @@ -28,6 +29,7 @@ const program = new commander.Command(packageFile.name)
'override default page like New Tab, Bookmarks, or History page'
)
.option('--devtools', 'add features to Chrome Developer Tools')
.option('--no-cross-browser', `the generated project will not be cross-browser compatible`)
.on('--help', () => {
console.log(` Only ${chalk.green('<project-directory>')} is required.`);
})
Expand Down Expand Up @@ -90,7 +92,7 @@ function logOptionsConflictError() {
process.exit(1);
}

function createExtension(name, { overridePage, devtools }) {
function createExtension(name, { overridePage, devtools, crossBrowser }) {
const root = path.resolve(name);
let overridePageName;

Expand Down Expand Up @@ -126,8 +128,8 @@ function createExtension(name, { overridePage, devtools }) {

appPackage.scripts = {
watch:
'webpack --mode=development --watch --config config/webpack.config.js',
build: 'webpack --mode=production --config config/webpack.config.js',
`webpack --mode=development --env.CROSS_BROWSER=${crossBrowser} --watch --config config/webpack.config.js`,
build: `webpack --mode=production --env.CROSS_BROWSER=${crossBrowser} --config config/webpack.config.js`,
};

// Create package file in project directory
Expand All @@ -148,7 +150,8 @@ function createExtension(name, { overridePage, devtools }) {
'size-plugin',
'mini-css-extract-plugin',
'css-loader',
'file-loader'
'file-loader',
'webextension-polyfill'
);

console.log('Installing packages. This might take a couple of minutes.');
Expand Down Expand Up @@ -176,7 +179,36 @@ function createExtension(name, { overridePage, devtools }) {
templateName = 'popup';
}

fs.copySync(path.resolve(__dirname, 'templates', templateName), root);
const files = [];
fs.copySync(path.resolve(__dirname, 'templates', templateName), root, {
filter: filename => {
const endsWithNoCrossbrowser = /\.nocrossbrowser\.js$/.test(filename); // determine if filename ends with '.nocrossbrowser.js'
if(!/\.js$/.test(filename)) return true; // copy all files that aren't .js files
if(/webpack\.config\.js$/.test(filename)) return true; // explcitly copy webpack.config.js all the time
if(!crossBrowser && endsWithNoCrossbrowser) {
files.push(filename);
return true;
} else if(crossBrowser && !endsWithNoCrossbrowser) {
return true;
} else if(!crossBrowser && !endsWithNoCrossbrowser) {
const parsedPath = path.parse(filename);
const pathWithCrossbrowser = path.resolve(parsedPath.dir, parsedPath.name, '.nocrossbrowser', parsedPath.ext);
return !fs.pathExists(pathWithCrossbrowser);
}
return false;
}
});

// if the webextenstion support is not enabled, we need to copy the template files with .nocrosbbrowser.js ending
// but after that, these files are renamed and the .nocrosbbrowser extension is removed
if(!crossBrowser) {
files.forEach(file => {
const { base } = path.parse(file);
let srcPath = path.resolve(root, 'src', base);
let destPath = path.resolve(root, 'src', base.replace('.nocrossbrowser', ''));
fs.moveSync(srcPath, destPath);
});
}

// Copy common webpack configuration file
fs.copySync(path.resolve(__dirname, 'config'), path.join(root, 'config'));
Expand Down Expand Up @@ -241,6 +273,13 @@ function createExtension(name, { overridePage, devtools }) {
};
}

if(crossBrowser) {
appManifest.background.scripts = [browserPolyfillFilename, ...appManifest.background.scripts];
if(appManifest.content_scripts) {
appManifest.content_scripts.forEach(i => i.js.unshift(browserPolyfillFilename));
}
}

// Create manifest file in project directory
fs.writeFileSync(
path.join(root, 'public', 'manifest.json'),
Expand Down Expand Up @@ -284,4 +323,5 @@ function createExtension(name, { overridePage, devtools }) {
createExtension(projectName, {
overridePage: program.overridePage,
devtools: program.devtools,
crossBrowser: program.crossBrowser
});
8 changes: 7 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"validate-npm-package-name": "^3.0.0"
},
"devDependencies": {
"prettier": "^1.18.2"
"prettier": "^1.18.2",
"webextension-polyfill": "^0.5.0"
}
}
22 changes: 11 additions & 11 deletions templates/devtools/config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

const merge = require('webpack-merge');

const common = require('./webpack.common.js');
const getCommonConfig = require('./webpack.common.js');
const PATHS = require('./paths');

// Merge webpack configuration files
const config = merge(common, {
entry: {
devtools: PATHS.src + '/devtools.js',
panel: PATHS.src + '/panel.js',
background: PATHS.src + '/background.js',
},
});

module.exports = config;
module.exports = env => {
// Merge webpack configuration files
return merge(getCommonConfig(env), {
entry: {
devtools: PATHS.src + '/devtools.js',
panel: PATHS.src + '/panel.js',
background: PATHS.src + '/background.js',
},
});
}
1 change: 1 addition & 0 deletions templates/devtools/public/devtools.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<title>Chrome DevTools</title>
</head>
<body>
<%= browser-polyfill %>
<script src="devtools.js"></script>

<!--
Expand Down
1 change: 1 addition & 0 deletions templates/devtools/public/panel.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
</main>
</div>

<%= browser-polyfill %>
<script src="panel.js"></script>

<!--
Expand Down
10 changes: 5 additions & 5 deletions templates/devtools/src/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
// With background scripts you can communicate with popup
// and contentScript files.
// For more information on background script,
// See https://developer.chrome.com/extensions/background_pages
// See https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.type === 'GREETINGS') {
const message = `Hi Pan, my name is Bac. I am from Background. It's great to hear from you.`;

// Log message coming from the `request` parameter
console.log(request.payload.message);
// Send a response message
sendResponse({
message,
});
// Send a response message using a Promise
// See: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage
return Promise.resolve({ message });
}
});
19 changes: 19 additions & 0 deletions templates/devtools/src/background.nocrossbrowser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';

// With background scripts you can communicate with popup
// and contentScript files.
// For more information on background script,
// See https://developer.chrome.com/extensions/background_pages

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.type === 'GREETINGS') {
const message = `Hi Pan, my name is Bac. I am from Background. It's great to hear from you.`;

// Log message coming from the `request` parameter
console.log(request.payload.message);
// Send a response message
sendResponse({
message,
});
}
});
4 changes: 2 additions & 2 deletions templates/devtools/src/devtools.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

// A DevTools extension adds functionality to the Chrome DevTools.
// For more information on DevTools,
// See https://developer.chrome.com/extensions/devtools
// See https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels

// Create a panel named `My Panel`
chrome.devtools.panels.create('My Panel', '', 'panel.html', panel => {
browser.devtools.panels.create('My Panel', '', 'panel.html').then( panel => {
console.log('Panel was successfully created!');
});
10 changes: 10 additions & 0 deletions templates/devtools/src/devtools.nocrossbrowser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';

// A DevTools extension adds functionality to the Chrome DevTools.
// For more information on DevTools,
// See https://developer.chrome.com/extensions/devtools

// Create a panel named `My Panel`
chrome.devtools.panels.create('My Panel', '', 'panel.html', panel => {
console.log('Panel was successfully created!');
});
Loading